netcore vue grpc、http grpc
vue 前端
一、项目准备
- 创建 vue 项目
$ cd E:\code# 创建 vue 项目 $ vue create apricot-grpc-> 1、选择 Vue3 - 安装依赖
$ npm install grpc-web --save$ npm install google-protobuf --save - 安装
proto转换依赖$ npm install -g protoc-gen-js protoc-gen-grpc-web grpc-tools
二、Proto 文件转换
-
复制
proto文件- 后端 proto
- 将
Protos文件夹复制至src目录下
-
查看全局目录地址
$ npm config get prefix -
找到
protoc.exe
-
生成
js文件- 将所有项目需要
.proto转换成.js# 转到 src 目录 $ cd .\aproct-grpc\src# 创建 grpc-proto-js 目录(输出js目录) $ mkdir grpc-proto-js# 生成 file_grpc_web_pb.js、file_pb.js $ D:\nodejs\node_modules\grpc-tools\bin\protoc.exe --proto_path=. --js_out=import_style=commonjs,binary:./grpc-proto-js/ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./grpc-proto-js/ .\Protos\File\file.proto# 生成 google\protobuf\empty_pb.js $ D:\nodejs\node_modules\grpc-tools\bin\protoc.exe --proto_path=. --js_out=import_style=commonjs,binary:./grpc-proto-js/ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./grpc-proto-js/ .\Protos\google\protobuf\empty.proto# 生成 Params\id_pb.js $ D:\nodejs\node_modules\grpc-tools\bin\protoc.exe --proto_path=. --js_out=import_style=commonjs,binary:./grpc-proto-js/ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./grpc-proto-js/ .\Protos\Params\id.proto # 生成 Params\query_pb.js $ D:\nodejs\node_modules\grpc-tools\bin\protoc.exe --proto_path=. --js_out=import_style=commonjs,binary:./grpc-proto-js/ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./grpc-proto-js/ .\Protos\Params\query.proto # 生成 Results\result_pb.js $ D:\nodejs\node_modules\grpc-tools\bin\protoc.exe --proto_path=. --js_out=import_style=commonjs,binary:./grpc-proto-js/ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./grpc-proto-js/ .\Protos\Results\result.proto - proto_path:
proto文件地址 - mode:请求数据类型(
Content-Type) - grpc-proto-js:生成
.js输出目录
- 将所有项目需要
-
使用 grpc
<template><div class="hello"><label for="grpc api">grpc api</label>:<inputname="refulapi"type="button"value="grpc api"v-on:click="onGrpcApi"/></div> </template><script>import { Empty } from "../grpc-proto-js/Protos/google/protobuf/empty_pb";import { FileServiceClient } from "../grpc-proto-js/Protos/File/file_grpc_web_pb";export default {name: "HelloWorld",props: {msg: String,},methods: {// eslint-disable-next-lineonGrpcApi(event) {const client = new FileServiceClient("http://localhost:5211", null, null);// eslint-disable-next-lineclient.readFileAsync(new Empty(), {}, (err, response) => {console.log(response);});},},}; </script> -
启动项目
$ npm run serve- 可能会出现错误:
not found Any_pb.js - 附图:

- 解决:
将 grpc-proto-js 下相关引用 Any_pb.js 改成 any_pb.js
- 可能会出现错误:
-
请求跨域
- 附图:

- 附图:
-
待续
三、grpc http
- http 请求
<template><div class="hello"><label for="reful api">grpc http api</label>:<inputname="refulapi"type="button"value="grpc http api"v-on:click="onGrpcHttpApi"/> </template><script>import { Empty } from "../grpc-proto-js/Protos/google/protobuf/empty_pb";import { FileServiceClient } from "../grpc-proto-js/Protos/File/file_grpc_web_pb";export default {name: "HelloWorld",props: {msg: String,},methods: {// eslint-disable-next-lineonGrpcHttpApi(event) {var xhr = new XMLHttpRequest();xhr.responseType = "json";xhr.addEventListener("readystatechange", function () {// eslint-disable-next-lineif (this.readyState === 4) {console.log(this.response.data);}});//设置请求xhr.open("get", "http://localhost:5211/v1/electron/getbase64");xhr.setRequestHeader("Content-Type", "application/json");xhr.send();},}}; </script> - 待续
后端
一、grpc proxy
- 创建项目
- 跳过,详细参考 [netcore grpc]
- 安装依赖
> dotnet add package Grpc.AspNetCore --version 2.71.0 > dotnet add package protobuf-net --version 3.2.56 > dotnet add package Yarp.ReverseProxy --version 2.3.0 - 创建
Proto- 跳过,参考上文
- 创建服务
/// <summary> /// Grcp service /// </summary> public class FileService : Electron.Grpc.FileService.FileServiceBase {public override async Task<GetBufferResponse> ReadFileAsync(Empty request, ServerCallContext context){using var fileStream = System.IO.File.OpenRead("C:\\Users\\Administrator\\Desktop\\2fdda3cc7cd98d1001e9f6a7b36eaf0e7bec54e73a51.jpg");var memeoryStream = new MemoryStream();await fileStream.CopyToAsync(memeoryStream);var buffer = memeoryStream.ToArray();var resp = new GetBufferResponse{Code = 200,Data = Convert.ToBase64String(buffer)};return resp;} } - 服务配置
using Apricot.Grpc.Proxy.Services;var builder = WebApplication.CreateBuilder(args);// yarp proxy builder.Services.AddReverseProxy();// grpc builder.Services.AddGrpc();// cors builder.Services.AddCors(options => {options.AddPolicy("AllowAll", policy =>{policy.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials().WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding", "X-Grpc-Web", "User-Agent");}); });var app = builder.Build();// route app.UseRouting();// grpc web app.UseGrpcWeb();app.UseCors("AllowAll");// grpc service app.MapGrpcService<FileService>().EnableGrpcWeb();// frontend(http://localhost:8081) proxy app.MapForwarder("/electron.FileService/{**catch-all}", "http://localhost:8081");app.Run(); Yarp.ReverseProxy跨域代理- 未找到更优方案,有更好方案评论区留言
- 解决
using Apricot.Grpc.Proxy.Services;var builder = WebApplication.CreateBuilder(args);// yarp proxybuilder.Services.AddReverseProxy();// corsbuilder.Services.AddCors(options =>{options.AddPolicy("AllowAll", policy =>{policy.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials().WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding", "X-Grpc-Web", "User-Agent");});});var app = builder.Build();// use corsapp.UseCors("AllowAll");// frontend(http://localhost:8081) proxyapp.MapForwarder("/electron.FileService/{**catch-all}", "http://localhost:8081");app.Run();
- 处理
Unsupported Media Type- 参考
- 解决
// route app.UseRouting();// grpc web app.UseGrpcWeb();// grpc service (EnableGrpcWeb) app.MapGrpcService<FileService>().EnableGrpcWeb();
- 待续
二、grpc http
- 安装依赖 [官网]
> dotnet add package Microsoft.AspNetCore.Grpc.JsonTranscoding --version 8.0.21 - 更改
proto协议syntax = "proto3"; option csharp_namespace = "Apricot.Electron.Grpc";package electron;// google protos import "google/protobuf/empty.proto"; import "google/protobuf/Any.proto"; import "google/api/annotations.proto";// results protos import "Protos/Results/result.proto"; import "Protos/File/buffer.proto";// services service FileService{rpc ReadFileAsync(google.protobuf.Empty) returns(GetBufferResponse);rpc GetBase64Async(google.protobuf.Empty) returns(GetBufferResponse){option (google.api.http) = {get: "/v1/electron/getbase64"};} } - 添加服务
- 服务配置
using Apricot.Grpc.Proxy.Services;var builder = WebApplication.CreateBuilder(args); // grpc builder.Services.AddGrpc().AddJsonTranscoding();// cors builder.Services.AddCors(options => {options.AddPolicy("AllowAll", policy =>{policy.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials().WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding", "X-Grpc-Web", "User-Agent");}); });var app = builder.Build();// route app.UseRouting();// cors app.UseCors("AllowAll");// grpc service app.MapGrpcService<FileService>();app.Run(); - 待续