zoukankan      html  css  js  c++  java
  • gRPC java 客户端,服务器端通讯使用json格式

    使用 protobuf 作为通讯内容序列化的简单例子请看:http://www.cnblogs.com/ghj1976/p/5458176.html

    本文是使用 json 做为内容序列化的简单例子。

    新建例子项目,从 proto 文件产生 通讯包的方式跟之前的完全一样。

    本文的源码在:

    https://github.com/grpc/grpc-java/tree/master/examples/src/main/java/io/grpc/examples/helloworld 这里的

    HelloJsonServer.java 和  HelloJsonClient.java 这两个文件中。

     

    这个文件跟 protobuf 处理的文件不同的地方如下:

    定义一个JSON解析的Stub

    整个类的定义文件如下:

    package com.ghj1976;

    import io.grpc.examples.helloworld.GreeterGrpc;
    import io.grpc.examples.helloworld.HelloReply;
    import io.grpc.examples.helloworld.HelloRequest;
    import io.grpc.stub.AbstractStub;
    import static io.grpc.stub.ClientCalls.blockingUnaryCall;
    import io.grpc.CallOptions;
    import io.grpc.Channel;
    import io.grpc.MethodDescriptor;
    import io.grpc.protobuf.ProtoUtils;


    /**
    * Created by ghj1976 on 16/5/4.
    */
    public  class HelloWorldJSONStub extends AbstractStub<HelloWorldJSONStub>
            implements io.grpc.examples.helloworld.GreeterGrpc.GreeterBlockingClient {

        static final MethodDescriptor<HelloRequest, HelloReply> METHOD_SAY_HELLO =
                MethodDescriptor.create(
                        GreeterGrpc.METHOD_SAY_HELLO.getType(),
                        GreeterGrpc.METHOD_SAY_HELLO.getFullMethodName(),
                        ProtoUtils.jsonMarshaller(HelloRequest.getDefaultInstance()),
                        ProtoUtils.jsonMarshaller(HelloReply.getDefaultInstance()));

        protected HelloWorldJSONStub(Channel channel) {
            super(channel);
        }

        protected HelloWorldJSONStub(Channel channel, CallOptions callOptions) {
            super(channel, callOptions);
        }

        @Override
        protected HelloWorldJSONStub build(Channel channel, CallOptions callOptions) {
            return new HelloWorldJSONStub(channel, callOptions);
        }

        @Override
        public HelloReply sayHello(HelloRequest request) {
            return blockingUnaryCall(
                    getChannel(), METHOD_SAY_HELLO, getCallOptions(), request);
        }
    }
    具体的解析用的 ProtoUtils.jsonMarshaller() 这个函数。

     

    服务器端的修改

    服务器端代码封装个函数, bindService, 用于服务器的数据解析分层。

    private ServerServiceDefinition bindService(final GreeterGrpc.Greeter serviceImpl){
        return io.grpc.ServerServiceDefinition.builder(GreeterGrpc.SERVICE_NAME)
                .addMethod(
                        com.ghj1976.HelloWorldJSONStub.METHOD_SAY_HELLO,
                        asyncUnaryCall(
                            new ServerCalls.UnaryMethod<HelloRequest,HelloReply>(){
                                @Override
                                public void invoke(HelloRequest request,StreamObserver<HelloReply> responseObserver){
                                    serviceImpl.sayHello(request,responseObserver);
                                }
                            }
                        ))
                .build();
    }
    这里用到了我们前面定义的方法

    com.ghj1976.HelloWorldJSONStub.METHOD_SAY_HELLO,

    增加服务时用这个 bindService 做封装。

    image

     

    服务端的代码改造就这些。

     

     

    客户端的代码改造

    只需要修改 Stub 为我们刚刚建立的 HelloWorldJSONStub  接口。

    image

     

    执行方法跟之前完全一样, 启动 main 方法即可。

     

    使用 Wireshark 监听网络请求,可以看到这时候发送的数据包:

    客户端请求的数据包:

    image

    服务器端返回的包:

    image

    使用 protobuf 时,则会是如下的截图:

    image

    image

  • 相关阅读:
    JS魔法堂:jQuery.Deferred(jQuery1.5-2.1)源码剖析
    JS魔法堂:ASI(自动分号插入机制)和前置分号
    JS魔法堂:初探传说中的setImmediate函数
    JS魔法堂:LINK元素深入详解
    JS魔法堂:IMG元素加载行为详解
    JS魔法堂:函数节流(throttle)与函数去抖(debounce)
    JS魔法堂:从void 0 === undefined说起
    JS魔法堂:jsDeferred源码剖析
    前端翻译:Promises/A+规范
    JS魔法堂:剖析源码理解Promises/A规范
  • 原文地址:https://www.cnblogs.com/ghj1976/p/5462071.html
Copyright © 2011-2022 走看看