grpcweb 客户端请求grpc-java服务器

news2024/9/25 9:41:19

1. 定义grpc  proto文件:HelloWorld.proto

syntax = "proto3";

option java_package = "ex.grpc";
option objc_class_prefix = "HSW";

package helloworld;


service Greeter {
  rpc sayHello (HelloRequest) returns (HelloReply) {}

  rpc printAge (printAgeRequest) returns (printAgeReply) {}
}

message HelloRequest {
  string name = 1;
  string city = 2;
}

message HelloReply {
  string message = 1;
}

message printAgeRequest {
  string age = 1;
}

message printAgeReply {
  string text = 1;
}

2. java grpc服务

package com.storehelper.core.grpc;

import com.storehelper.grpc.common.RESPONSE_CODE;
import com.storehelper.grpc.passport.LoginRequest;
import com.storehelper.grpc.passport.LoginResponse;
import com.storehelper.grpc.passport.PassportServiceGrpc;
import com.storehelper.grpc.passport.TokenInfo;
import ex.grpc.GreeterGrpc;
import ex.grpc.HelloWorld;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

import java.io.IOException;

public class CalculatorServer {

    public static void main(String[] args) throws IOException, InterruptedException {
        Server server = ServerBuilder.forPort(8082)
                //.addService(new PassportServiceImpl())
                .addService(new GreeterServiceImpl())
                .build();

        server.start();
        System.out.println("Server started at " + server.getPort());
        server.awaitTermination();
    }

    static class PassportServiceImpl extends PassportServiceGrpc.PassportServiceImplBase {
        @Override
        public void login(LoginRequest request, StreamObserver<LoginResponse> responseObserver) {
            LoginResponse response = null;
            response = LoginResponse.newBuilder()
                    .setCode(RESPONSE_CODE.SUCCESS)
                    .setMessage("登录成功")
                    .build();
            responseObserver.onNext(response);

            responseObserver.onCompleted();
        }
    }

    static class GreeterServiceImpl extends GreeterGrpc.GreeterImplBase{
        @Override
        public void sayHello(HelloWorld.HelloRequest request, StreamObserver<HelloWorld.HelloReply> responseObserver) {
            HelloWorld.HelloReply response = HelloWorld.HelloReply.newBuilder().setMessage("111").build();
            responseObserver.onNext(response);

            responseObserver.onCompleted();
        }

        @Override
        public void printAge(HelloWorld.printAgeRequest request, StreamObserver<HelloWorld.printAgeReply> responseObserver) {
            super.printAge(request, responseObserver);
        }
    }
}

3. grpc-web js生成

protoc   --js_out=import_style=commonjs:./src/protoc  --grpc-web_out=import_style=commonjs,mode=grpcweb:./src/protoc -I=src\protoc\     .\src\protoc\HelloWorld.proto

或者 ts生成

protoc   --js_out=import_style=commonjs:./src/protoc  --grpc-web_out=import_style=typescript,mode=grpcweb:./src/protoc -I=src\protoc\     .\src\protoc\HelloWorld.proto

4. grpc-web代码

<script>
import {
  GreeterClient
} from '@/protoc/HelloWorld_grpc_web_pb.js';
import { HelloRequest } from '@/protoc/HelloWorld_pb.js';



const client = new GreeterClient('http://localhost:8081/');

const helloRequest = new HelloRequest();
helloRequest.setCity('北京');
helloRequest.setName("11");
 
const metadata = {"Content-Type": "aplication/grpc"};//aplication/grpc

console.log(111111111111);
client.sayHello(helloRequest, metadata, (err, response) => {
  console.log(22222222);
  console.log(err, response);
  console.log(response.getMessage());
});
</script>

5.grpc-web代理:nginx

location / {
      
		
		  # 重点!!需要将Content-Type更改为 application/grpc
    # grpc-web过来的是application/grpc-web+proto || application/grpc-web+text (取决于生成js代码时grpc-web_out 的mode选项,本文用grpcweb 则为application/grpc-web+proto)
    grpc_set_header Content-Type application/grpc;
    grpc_pass localhost:8082;
    # 因浏览器有跨域限制,这里直接在nginx支持跨域
    if ($request_method = 'OPTIONS') {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web';
      add_header 'Access-Control-Max-Age' 1728000;
      add_header 'Content-Type' 'text/plain charset=UTF-8';
      add_header 'Content-Length' 0;
      return 204;
    }

    if ($request_method = 'POST') {
      add_header 'Access-Control-Allow-Origin' '*';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web';
      add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding, grpc-message,grpc-status';
    }
  }

参考文档:

https://segmentfault.com/a/1190000022022271

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2163187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

scrapy 爬取微博(四)【最新超详细解析】: 设计篇

一、功能设计 开始开发之前我们先对本文的scrapy微博爬虫工程进行一个功能的设计&#xff0c;包含的功能模块如下&#xff1a; 功能模块具体描述微博文章爬取根据关键词、时间范围等参数爬取微博文章&#xff0c;获取用户名、ID、微博mid、微博内容、点赞、转发、评论等数据微…

全国各省市生产总值指数-工业增加值指数(1999-2020年)

工业增加值指的是工业企业在一定时期内通过生产活动创造的新增价值&#xff0c;它等于工业总产值减去工业中间投入的差额。这一指标的计算可以采用生产法和收入法两种方式。生产法通过计算工业总产值与中间消耗的差额来得到&#xff0c;而收入法则将工业增加值视为固定资产折旧…

HarmonyOS Next(纯血鸿蒙)它到底像谁

前言 24年的第1天有写过一篇关于鸿蒙的文章&#xff1a;不吹不黑&#xff0c;辩证看待开发者是否需要入坑鸿蒙 后续再也没有写关于鸿蒙的文章。 没错&#xff0c;我确实入坑了鸿蒙&#xff0c;并且成功上架了几款App和元服务&#xff0c;虽然当前的用户量还比较少&#xff0c…

微信小程序——引入 iconfont 矢量图标,如何使用引用阿里巴巴矢量图标

本文介绍如何在小程序中加入图标&#xff0c;效果如下图&#xff1a; 1、访部iconfont-阿里巴巴矢量图标库 找到需要的图标&#xff0c;然后添加入库 将增加好的图标添加到项目中 2、点击更新生成代码 生成后如下图 3、打开生成的css样式文件 4、在小程序中新建/static/iconfon…

利士策分享,如何在有限的时间内过上富足的生活?

利士策分享&#xff0c;如何在有限的时间内过上富足的生活&#xff1f; 在快节奏的现代生活中&#xff0c;追求富足不仅仅是物质上的丰盈&#xff0c;更是心灵的满足与生活的平衡。 如何在有限的时间内实现这一目标&#xff0c;是许多人心中的疑问。 以下是一些实用建议&#…

Ubuntu 20.04 内核升级后网络丢失问题的解决过程

在 Ubuntu 系统中&#xff0c;内核升级是一个常见的操作&#xff0c;旨在提升系统性能、安全性和兼容性。然而&#xff0c;有时这一操作可能会带来一些意外的副作用&#xff0c;比如导致网络功能的丧失。 本人本来是想更新 Nvidia 显卡的驱动&#xff0c;使用 ubuntu-drivers …

postman中使用Pre-request Script

一、get方法 get请求时 &#xff0c;有多个params&#xff0c;并且有一个参数为sign&#xff0c;这个参数是有其他params拼接之后md5加密得到的&#xff0c;如何通过js语句获取params参数并生成sign。 const CryptoJS require(crypto-js); // 引入 CryptoJS 库进行 MD5 加密…

安卓数据存储——SQLite

一、SQLite数据库 创建表 CREATE TABLE IF NOT EXISTS user_info (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,name VARCHAR NOT NULL,age INTEGER NOT NULL,height LONG NOT NULL,weight FLOAT NOT NULL);注&#xff1a; IF NOT EXISTS&#xff1a;如果该表不存在则创…

Docker更换阿里容器镜像源

以Mac为例&#xff0c; 一、获取阿里容器镜像加速器地址 访问阿里云官网https://cn.aliyun.com/ 登录阿里云&#xff0c;没有账号就注册一个 登录完成后在搜索框搜索&#xff0c;容器镜像服务&#xff0c;并打开 点击管理控制台&#xff0c;进入管理控制台 左侧点击镜像加速…

ubuntu重新安装clickhouse

1.卸载clickhouse 关闭原来的clickhouse sudo systemctl stop clickhouse-server 查看关闭clickhouse是否成功 sudo systemctl status clickhouse-server 备份配置文件 /etc/clickhouse-server/user.xml /etc/clickhouse-server/config.d/metrika.xml /etc/clickhouse…

蚂蚁Raft一致性算法库SOFAJRaft深入分析

大家好&#xff0c;我是 V 哥&#xff0c;SOFAJRaft 是蚂蚁金服开源的一个基于 Raft 共识算法的 Java 实现&#xff0c;它特别适合高负载、低延迟的分布式系统场景。SOFAJRaft 支持 Multi-Raft-Group&#xff0c;能够同时处理多个 Raft 集群&#xff0c;具有扩展性和强一致性保…

实验室ICPR 2024论文分享┆FPMT: 基于增强型半监督模型的交通事件检测(含详细视频解读)

目录 论文分享简介 1. 会议介绍 2. 研究背景及主要贡献 3. 方法 4. 实验 5. 结论 6. 论文介绍视频 论文分享简介 本推文详细介绍了一篇实验室的最新论文成果《FPMT: Enhanced Semi-Supervised Model for Traffic Incident Detection》&#xff0c;该论文已被第27届国际…

尚硅谷———-乐(智)尚代驾~~--------Day5----司机认证篇~

前言&#xff1a; Hello亲爱的uu们&#xff0c;在读过了一个愉快的周末后&#xff08;摸鱼了一会&#xff09;&#xff0c;我又回来更新啦&#xff0c;感谢uu们的阅读&#xff0c;话不多说~ 司机认证 当司机点击开始接单的时候&#xff0c;会先判断该司机有没有通过认证&…

关于PCA的一份介绍

在这篇文章中&#xff0c;我将介绍机器学习中的一种无监督学习算法——PCA&#xff0c;因为它主要有两种用途&#xff0c;即降维与特征提取&#xff0c;所以我将将围绕这两种用途来介绍它&#xff0c;包括基本概念&#xff0c;应用与代码实践。 一、 PCA 1.1 概念 PCA&#…

dev containers plugins for vscode构建虚拟开发环境

0. 需求说明 自用笔记本构建一套开发环境&#xff0c;用docker 虚拟插件 dev containers,实现开发环境的构建&#xff0c;我想构建一套LLMs的环境&#xff0c;由于环境配置太多&#xff0c;不想污染本地环境&#xff0c;所以选择隔离技术 1. 环境准备 vscodedocker 2. 步骤…

任意长度并行前缀和 扫描算法 《PMPP》笔记

下面的算法针对于任意长度输入 对于大数据集&#xff0c;首先将输入分为几段&#xff0c;每一段放进共享内存并用一个线程块处理&#xff0c;比如一个线程块使用1024个线程的话&#xff0c;每个块最多能处理2048个元素。 在前面代码中&#xff0c;一个块最后的执行结果保存到了…

桥接模式和NET模式的区别

桥接模式和NET模式的区别 NAT模式&#xff1a; NAT&#xff1a;网络地址转换&#xff08;模式&#xff09;&#xff1a;借助宿主机来上网&#xff0c;没桥接那么麻烦&#xff0c;只用配置DNS即可。 缺点&#xff1a;扎根于宿主机&#xff0c;不能和局域网内其它真实的主机进行…

用Python实现运筹学——Day 2: 线性规划的基本概念

一、学习内容 线性规划的定义&#xff1a; 线性规划&#xff08;Linear Programming, LP&#xff09;是一种用于求解约束条件下线性目标函数最优解的方法。线性规划问题通常涉及最大化或最小化一个线性目标函数&#xff0c;目标函数的变量受一组线性不等式或等式的约束。 目标…

C语言 | Leetcode C语言题解之第435题无重叠区间

题目&#xff1a; 题解&#xff1a; int cmp(int** a, int** b) {return (*a)[1] - (*b)[1]; }int eraseOverlapIntervals(int** intervals, int intervalsSize, int* intervalsColSize) {if (intervalsSize 0) {return 0;}qsort(intervals, intervalsSize, sizeof(int*), cm…

【React】Ant Design 5.x版本drawer抽屉黑边问题

环境 antd: ^5.14.1react: ^18 问题情况 <Drawer open{open} closable{false} mask{false} width{680}getContainer{props.getContainer || undefined}><p>Some contents...</p><p>Some contents...</p><p>Some contents...</p> …