netcore vue grpc、http grpc
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>: <input name="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-line onGrpcApi(event) { const client = new FileServiceClient("http://localhost:5211", null, null); // eslint-disable-next-line client.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>: <input name="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-line onGrpcHttpApi(event) { var xhr = new XMLHttpRequest(); xhr.responseType = "json"; xhr.addEventListener("readystatechange", function () { // eslint-disable-next-line if (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 proxy builder.Services.AddReverseProxy(); // 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(); // use cors app.UseCors("AllowAll"); // frontend(http://localhost:8081) proxy app.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" }; } } - 添加服务
/// <summary> /// Grcp service /// </summary> public class FileService : Electron.Grpc.FileService.FileServiceBase { public override async Task<GetBufferResponse> GetBase64Async(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); // 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(); - 待续
示例项目
如有帮助,欢迎转载,转载请注明原文链接:https://www.cnblogs.com/study10000/p/19165140

浙公网安备 33010602011771号