grpc-demo

---gRPC  是一个高性能、开源和通用的 gooogle开发RPC 框架,基于 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

---以上的特性我们可以使用grpc取代http用与移动端和后台服务器之间的通信,还有服务与服务之间的通信。这样对于互联网公司来说,即减少了开发难度,又提高了效率。

---使用grpc,必须先了解protobuf,protobuf是谷歌自定义的序列化格式,类似与json,xml,只是json语义太弱,xml太笨重,而protobuf正结合了他们的优点。java使用protobuf的话必须要用maven插件,使之生成代码。

以下是一个简单的demo。

---分为两个工程:一个protobuf工程,一个是实现grpc的客户端和服务端

protobuf:

grpc-demo_第1张图片

注意:该工程只有一个protobuf文件user.proto,这个文件必须要在src->main->proto目录下,否则打包不了。pom.xml配置如下:


	4.0.0

	com.yyc.simple
	protobuf
	0.0.1-SNAPSHOT
	simple

	
		UTF-8
		0.13.2
	

	
		
		
            io.grpc
            grpc-core
            ${grpc.version}
        
        
            io.grpc
            grpc-protobuf
            ${grpc.version}
        
        
            io.grpc
            grpc-netty
            ${grpc.version}
        
        
            io.grpc
            grpc-stub
            ${grpc.version}
        
        
            com.orbitz.consul
            consul-client
            0.10.0
        
	

	
		
			
				kr.motd.maven
				os-maven-plugin
				1.4.1.Final
			
		
		
			
				org.xolstice.maven.plugins
				protobuf-maven-plugin
				0.5.0
				
					
					com.google.protobuf:protoc:3.0.0-beta-2:exe:${os.detected.classifier}
					grpc-java
					io.grpc:protoc-gen-grpc-java:0.13.2:exe:${os.detected.classifier}
				
				
					
						
							compile
							compile-custom
						
					
				
			
		
	

还有一个工程 grpc的客户端和服务端,pom.xml引用上面的工程

编写服务端实现如下:

import java.io.IOException;

import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.Server;
import io.grpc.ServerCall;
import io.grpc.ServerCall.Listener;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.ServerInterceptors;
import io.grpc.examples.demo.DemoProto.LoginRequest;
import io.grpc.examples.demo.DemoProto.LoginResponse;
import io.grpc.examples.demo.DemoServiceGrpc;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyServerBuilder;
import io.grpc.netty.ProtocolNegotiators;
import io.grpc.stub.StreamObserver;
import io.grpc.testing.TestUtils;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;

public class GrpcService {
	private int port=8888;
	private Server server;

	private void start() throws IOException{
	    
	    /**
		 * 创建和启动一个服
		 */
		server = NettyServerBuilder.forPort(port).addService(ServerInterceptors.intercept(DemoServiceGrpc.bindService(new Serviceimpl()),echoRequestHeadersInterceptor()))
				.build().start();
		//protocolNegotiator  和  sslContext  useTransportSecurity是等效的
		/**
		 * 事件钩子  关闭的时候调用stop
		 */
		Runtime.getRuntime().addShutdownHook(new Thread(){
			@Override
		      public void run() {
		        System.err.println("*** shutting down gRPC server since JVM is shutting down");
		        GrpcService.this.stop();
		        System.err.println("*** server shut down");
		      }
		});
		
	}
	
	private void stop(){
		if(server!=null){
			server.shutdown();
		}
	}
	
	private void blockUntilShutdown() throws InterruptedException{
		 if (server != null) {
			 server.awaitTermination();
		 }
	}
	
	public static void main(String[] args) throws IOException, InterruptedException {
		final GrpcService grpcService = new GrpcService();
		grpcService.start();
		grpcService.blockUntilShutdown();
	}
	
	public static ServerInterceptor echoRequestHeadersInterceptor() {
	    return new ServerInterceptor() {
			public  Listener interceptCall(MethodDescriptor method,
					ServerCall call, Metadata headers, ServerCallHandler next) {
				System.out.println("服务器过滤器method"+method.toString()+"sss"+System.currentTimeMillis());
				System.out.println("服务器过滤器headers"+headers.toString());
				return next.startCall(method, call, headers);
			}
	     
	    };
	  }
	
}

/**
 * 实现DemoService服务
 * @author yeyc
 *
 */
class  Serviceimpl implements   DemoServiceGrpc.DemoService{

	public void login(LoginRequest request, StreamObserver responseObserver) {
		// TODO Auto-generated method stub
		
		System.out.println(request.getUserName()+"来登录");
		LoginResponse loginResponse = LoginResponse.newBuilder().setMsg(request.getUserName()+"授权登录成功").build();
		responseObserver.onNext(loginResponse);
		responseObserver.onCompleted();
	}
}

客户端实现:

package grpc;

import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLException;

import com.google.common.util.concurrent.ListenableFuture;

import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ClientCall;
import io.grpc.ClientInterceptor;
import io.grpc.LoadBalancer;
import io.grpc.ManagedChannel;
import io.grpc.MethodDescriptor;
import io.grpc.SimpleLoadBalancerFactory;
import io.grpc.TransportManager;
import io.grpc.examples.demo.DemoProto.LoginRequest;
import io.grpc.examples.demo.DemoProto.LoginResponse;
import io.grpc.examples.demo.DemoServiceGrpc;
import io.grpc.internal.GrpcUtil;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.testing.TestUtils;
import io.netty.handler.ssl.SslContext;

public class GrpcClient {
	private  ManagedChannel channel;
	/**
	 * 同步阻塞
	 */
	private DemoServiceGrpc.DemoServiceBlockingStub blockingStub;
	/**
	 * 异步非阻塞
	 */
	private DemoServiceGrpc.DemoServiceFutureStub futureStub;
	
	/**
	 * 创建channel  创建各种桩
	 * @param host
	 * @param port
	 * @throws IOException 
	 * @throws SSLException 
	 */
	void init(String host, int port) throws SSLException, IOException{

		SslContext sslContext = GrpcSslContexts.forClient().trustManager(TestUtils.loadCert("ca.pem")).build();
		/*String  tagert = GrpcUtil.authorityFromHostAndPort(host, port);
		System.out.println("tagert:"+tagert);*/
		channel =  NettyChannelBuilder.forAddress(host, port).usePlaintext(true).build();
		//.negotiationType(NegotiationType.PLAINTEXT)  和这个是等效  usePlaintext(true)
		
		
		blockingStub = DemoServiceGrpc.newBlockingStub(channel);
		futureStub = DemoServiceGrpc.newFutureStub(channel);
	}
	
	
	
	public void shutdowm() throws InterruptedException{
		if(channel!=null){
			channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
		}
	}
	
	
	
	public static void main(String[] args) throws InterruptedException, ExecutionException, SSLException, IOException {
		GrpcClient grpcClient = new GrpcClient();
		grpcClient.init("192.168.100.110", 8888);
		//构建请求参数
		LoginRequest request = LoginRequest.newBuilder().setUserName("yyc").build();
		//同步阻塞调用
		LoginResponse loginResponse = grpcClient.blockingStub.login(request);
		System.out.println("同步调用后返回"+loginResponse.getMsg());
		//异步非阻塞调用
		ListenableFuture  loginResponse2 = grpcClient.futureStub.login(request);
		LoginResponse loginResponseFuture =  loginResponse2.get();
		System.out.println("异步调用后返回"+loginResponseFuture.getMsg());
		grpcClient.shutdowm();
	}
	
}

这样一个完整grpcdemo就可以使用了。

学习grpc的的网址:http://doc.oschina.net/grpc

下面是博主另外一篇博客阐述了grpc的应用场景:基于grpc的服务化框架

grpc-demo github 介绍了grpc的基本使用包括加密,客户端服务端流的使用,拦截器等的使用

你可能感兴趣的:(服务框架)