> 文章列表 > grpc 使用demo示例

grpc 使用demo示例

grpc 使用demo示例

一、 编写proto文件

   1、idea新建java项目,在maven中引入以下依赖:

 <dependencies><!--grpc底层通信组件--><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty-shaded</artifactId><version>1.42.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>1.42.0</version></dependency><!--存根--><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>1.42.0</version></dependency><dependency><groupId>org.apache.tomcat</groupId><artifactId>annotations-api</artifactId><version>6.0.53</version><!--provided:只能作用在编译和测试时,同时没有传递性--><scope>provided</scope></dependency><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.9.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency></dependencies><build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.6.2</version></extension></extensions><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><protocArtifact>com.google.protobuf:protoc:3.17.3:exe:${os.detected.classifier}</protocArtifact><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.42.0:exe:${os.detected.classifier}</pluginArtifact></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins></build>

  2、proto文件

syntax = "proto3";
//生成java类所在的包
option java_package = "com.cn.news.proto";//生成多个类
option java_multiple_files = false;//生成外层类类名
option java_outer_classname = "NewsProto";//包名
package news;//grpc要调用的service
service NewsService{//list是方法名,NewsRequest代表传入参数,NewsResponse代表返回响应rpc list(NewsRequest) returns (NewsResponse){}
}//请求体
message NewsRequest{string date = 1;NewsDetail body = 2;
}//响应体
message NewsResponse{//repeated说明是一个集合(数组),数组每一个元素都是News对象repeated News news = 1;
}//News新闻实体对象
message News{//对应java的intint32 id = 1;//新闻标题string title = 2;//新闻内容string content = 3;//对应java的longint64 createTime = 4;
}message NewsDetail{//1表示热点新闻 2表示普通新闻int32 msgType = 1;//0未读 1-已读int32 msgStatus = 2;
}

 3. 编译并生成java文件

二、 编写grpc服务端

    1、实现  NewsServiceGrpc.NewsServiceImplBase 接口,提供服务方法调用

package com.cn.news.service;import com.cn.news.proto.NewsProto;
import com.cn.news.proto.NewsServiceGrpc;
import io.grpc.stub.StreamObserver;/*** description: NewService <br>* date: 23.4.12 15:52 <br>* author: cn_yaojin <br>* version: 1.0 <br>*/
public class NewService extends NewsServiceGrpc.NewsServiceImplBase {@Overridepublic void list(NewsProto.NewsRequest request, StreamObserver<NewsProto.NewsResponse> responseObserver) {String date = request.getDate();System.out.println("收到客户端请求了,时间:" + date + ",参数体:" + request.getBody().getMsgType());NewsProto.NewsResponse newList = null;try {NewsProto.NewsResponse.Builder newListBuilder = NewsProto.NewsResponse.newBuilder();String title = "";if (request.getBody().getMsgType() == 1) {title = "实时热点";} else if (request.getBody().getMsgType() == 2) {title = "精准扶贫";} else {title = "为人民服务";}NewsProto.News news = NewsProto.News.newBuilder().setId(request.getBody().getMsgType()).setTitle(title).setContent(request.getBody().getMsgType() + ":" + title).setCreateTime(System.currentTimeMillis()).build();newListBuilder.addNews(news);newList = newListBuilder.build();} catch (Exception e) {e.printStackTrace();responseObserver.onError(e);} finally {responseObserver.onNext(newList);}responseObserver.onCompleted();}
}

    2、 grpc服务端,启动

package com.cn.news.service;import io.grpc.Server;
import io.grpc.ServerBuilder;/*** description: GRpcServer <br>* date: 23.4.12 16:29 <br>* author: cn_yaojin <br>* version: 1.0 <br>*/
public class GRpcServer {public static void main(String[] args) {try {Server server = ServerBuilder.forPort(1031).addService(new NewService()).build().start();System.out.println("服务已启动,端口:" + server.getPort());server.awaitTermination();} catch (Exception e) {e.printStackTrace();}}}

三、 编写grpc客户端,启动

package com.cn.news.service;import com.cn.news.proto.NewsProto;
import com.cn.news.proto.NewsServiceGrpc;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** description: GRpcClient <br>* date: 23.4.12 16:32 <br>* author: cn_yaojin <br>* version: 1.0 <br>*/
public class GRpcClient {private NewsServiceGrpc.NewsServiceBlockingStub newsServiceImplBase;public GRpcClient(Channel channel) {this.newsServiceImplBase = NewsServiceGrpc.newBlockingStub(channel);}public static void main(String[] args) {//初始化client与服务端的连接ManagedChannel channel = ManagedChannelBuilder.forTarget("127.0.0.1:1031").usePlaintext().build();GRpcClient gRpcClient = new GRpcClient(channel);//定时任务模拟提交数据ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);scheduledExecutorService.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {//以下是构造请求参数NewsProto.NewsDetail.Builder detail = NewsProto.NewsDetail.newBuilder();long t = System.currentTimeMillis();if (t % 5 == 0) {detail.setMsgType(1);} else if (t % 5 == 1) {detail.setMsgType(3);} else {detail.setMsgType(2);}detail.setMsgStatus(0);NewsProto.NewsRequest request = NewsProto.NewsRequest.newBuilder().setDate(t + "").setBody(detail.build()).build();gRpcClient.list(request);}}, 10, 30, TimeUnit.SECONDS);try {Thread.sleep(Long.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}/*** 调用grpc的提供的服务(此处调用NewService下的list方法)** @param request*/public void list(NewsProto.NewsRequest request) {try {NewsProto.NewsResponse response = newsServiceImplBase.list(request);List<NewsProto.News> list = response.getNewsList();if (list != null) {for (NewsProto.News t : list) {System.out.println(String.format("收到服务端响应了,标题:%s,内容:%s,时间:%s", t.getTitle(), t.getContent(), t.getCreateTime()));}}} catch (Exception e) {e.printStackTrace();}}}

四、启动后的运行示例 

grpc服务端
grpc服务端

 

grpc客户端
grpc客户端

 五、 编写node客户端

const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');//以下proto文件与当前的index.js在同一个目录下
const PROTO_PATH = 'helloworld.proto';const packageDefinition = protoLoader.loadSync(PROTO_PATH);
const hello_proto = grpc.loadPackageDefinition(packageDefinition).news;function main() {const client = new hello_proto.NewsService('127.0.0.1:1031',grpc.credentials.createInsecure());var detail={msgType:2,msgStatus:2 };var user={date:123123123123,body: detail};client.list(user, function (err, response) {var items = response.newsconsole.log('Greeting:', items);});
}main();
node客户端运行结果