使用 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 做封裝。
服務端的代碼改造就這些。
客戶端的代碼改造
只需要修改 Stub 為我們剛剛建立的 HelloWorldJSONStub 接口。
執行方法跟之前完全一樣, 啟動 main 方法即可。
使用 Wireshark 監聽網絡請求,可以看到這時候發送的數據包:
客戶端請求的數據包:
服務器端返回的包:
使用 protobuf 時,則會是如下的截圖: