# 实现gRPC双向流模式通信 **Repository Path**: cocos_creater_projects/grpc-demo ## Basic Information - **Project Name**: 实现gRPC双向流模式通信 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-02 - **Last Updated**: 2025-04-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 实现gRPC的demo ### 1.初始化项目 ```bash npm init -y ``` ```bash tsc --init ``` ### 2.安装依赖 ```bash npm i @grpc/grpc-js grpc-tools grpc_tools_node_protoc_ts ``` ### 3.编写proto文件 新建test.proto文件并编写rpc接口和请求响应类型 ```proto syntax = "proto3"; package test; service Test { rpc SayTest (TestReq) returns (TestRes) {} } message TestReq { string name = 1; } message TestRes { string name = 1; } ``` ### 4.增加编译proto文件命令 ```bash "gen": "grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./gen --grpc_out=grpc_js:./gen --ts_out=grpc_js:./gen ./test.proto", ``` ### 5.新建gen文件夹,执行pnpm gen 生成js和ts文件 ### 6.编写Client端和Server端代码 新建server.ts ``` typescript import * as grpc from '@grpc/grpc-js' import { TestService } from './gen//test_grpc_pb' import { TestRes } from './gen/test_pb' const server = new grpc.Server() server.addService(TestService, { sayTest(call: any, callback: Function) { console.log(call.request.getName()) const res = new TestRes() res.setName('Test' + call.request.getName()) callback(null, res) }, }) server.bindAsync('localhost:3333', grpc.ServerCredentials.createInsecure(), (err, port) => { if (err) { console.error('Failed to bind:', err) return } console.log('RPC服务启动') }) ``` 新建client.ts ``` typescript import { TestClient } from './gen/test_grpc_pb' import * as grpc from '@grpc/grpc-js' import { TestReq } from './gen/test_pb' const client = new TestClient('localhost:3333', grpc.credentials.createInsecure()) const testReq = new TestReq() testReq.setName('client') client.sayTest(testReq, (err, res) => { if (err) { console.error(err) } console.log(res.getName()) }) ``` ### 7.新增运行脚本,并打开两个终端分别运行npm run:server 和 npm run:client ```bash "server": "ts-node server.ts", "client": "ts-node client.ts" ``` 运行完脚本后,发现server端接收到了client的信息,client端打印了自己的console.log(res.getName())这句话后,就中断了连接。 ### 8.实现grpc的双向流模式 1. 修改test.proto文件 ```proto syntax = "proto3"; package test; service Test { rpc SayTest (stream TestReq) returns (stream TestRes) {} } message TestReq { string name = 1; } message TestRes { string name = 1; } ``` 2. 修改server.ts文件 ``` typescript import * as grpc from '@grpc/grpc-js' import { TestService } from './gen//test_grpc_pb' import { TestRes } from './gen/test_pb' const server = new grpc.Server() server.addService(TestService, { sayTest(call: any, callback: Function) { call.on('data', (data: any) => { console.log('data', data) const res = new TestRes() res.setName('Test') call.write(res) }) }, }) server.bindAsync('localhost:3333', grpc.ServerCredentials.createInsecure(), (err, port) => { if (err) { console.error('Failed to bind:', err) return } console.log('RPC服务启动') }) ``` 3. 修改client.ts文件 ``` typescript import { TestClient } from './gen/test_grpc_pb' import * as grpc from '@grpc/grpc-js' import { TestReq } from './gen/test_pb' const client = new TestClient('localhost:3333', grpc.credentials.createInsecure()) const testReq = new TestReq() testReq.setName('client') const call = client.sayTest() call.on('data', (data: any) => { console.log('data', data) call.write(testReq) }) call.write(testReq) ``` 4. 重新启动两个服务运行npm run:server 和 npm run:client,会发现两个服务会不停地发消息,从而实现grpc的双向流模式