grpc加密TLS初体验(go、java版本)
grpc-go、java的安装编译helloworld可以参考如下文章
http://my.oschina.net/ysh3940/blog/403591
openssl的安装、生成秘钥证书可以参考如下文章
http://my.oschina.net/ysh3940/blog/464208
示例代码go版本
服务端代码
package main
import (
"fmt"
"log"
"net"
pb "github.com/grpc/grpc-common/go/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
const (
port = ":50051"
)
type server struct{}
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
fmt.Println("--->>> request name = ", in.Name)
return &pb.HelloReply{Message: "--->>> Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
fmt.Println(">>> server is starting in 127.0.0.1 and port " + port + " >>>")
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
creds, err := credentials.NewServerTLSFromFile("D:/BaiduYunDownload/server1.pem", "D:/BaiduYunDownload/server1.key")
if err != nil {
fmt.Println("Failed to generate credentials: ", err)
}
s.Serve(creds.NewListener(lis))
}
客户端代码
package main
import (
"log"
"os"
pb "github.com/grpc/grpc-common/go/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
const (
address = "127.0.0.1:50051"
defaultName = "world"
)
func main() {
var opts []grpc.DialOption
var creds credentials.TransportAuthenticator
var err error
creds, err = credentials.NewClientTLSFromFile("D:/BaiduYunDownload/ca.pem", "x.test.youtube.com")
if err != nil {
log.Fatalf("Failed to create TLS credentials %v", err)
}
opts = append(opts, grpc.WithTransportCredentials(creds))
conn, err := grpc.Dial(address, opts...)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
log.Printf(">>> connect success >>>")
defer conn.Close()
c := pb.NewGreeterClient(conn)
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)
}
示例代码java版本
服务端代码:
package io.grpc.examples.helloworld;
import io.grpc.ServerImpl;
import io.grpc.stub.StreamObserver;
import io.grpc.transport.netty.NettyServerBuilder;
import io.netty.handler.ssl.SslContext;
import java.io.File;
import java.util.logging.Logger;
public class HelloWorldServer {
private static final Logger logger = Logger
.getLogger(HelloWorldServer.class.getName());
private int port = 50051;
private ServerImpl server;
private void start() throws Exception {
@SuppressWarnings("deprecation")
SslContext sslContext = SslContext.newServerContext(new File(
"D:/BaiduYunDownload/server3.pem"), new File(
"D:/BaiduYunDownload/server3_pkcs8.key"));
server = NettyServerBuilder.forPort(port).sslContext(sslContext)
.addService(GreeterGrpc.bindService(new GreeterImpl())).build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err
.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
public static void main(String[] args) throws Exception {
final HelloWorldServer server = new HelloWorldServer();
server.start();
}
private class GreeterImpl implements GreeterGrpc.Greeter {
@Override
public void sayHello(HelloRequest req,
StreamObserver<HelloResponse> responseObserver) {
System.out.println("--->>> name = " + req.getName());
HelloResponse reply = HelloResponse.newBuilder()
.setMessage("Hello " + req.getName()).build();
responseObserver.onValue(reply);
responseObserver.onCompleted();
}
}
}
客户端代码:
package io.grpc.examples.helloworld;
import io.grpc.ChannelImpl;
import io.grpc.transport.netty.NegotiationType;
import io.grpc.transport.netty.NettyChannelBuilder;
import io.netty.handler.ssl.SslContext;
import java.io.File;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;
public class HelloWorldClient {
private static final Logger logger = Logger
.getLogger(HelloWorldClient.class.getName());
private final ChannelImpl channel;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
public HelloWorldClient(String host, int port) throws SSLException,
NoSuchAlgorithmException {
@SuppressWarnings("deprecation")
// 这里要注意下由于java版本的没有提供像go那样的可以指定域名
// java版本源代码中把host传入作为证书域名
// 域名是在证书生成的过程中自己输入的
SslContext sslContext = SslContext.newClientContext(new File(
"D:/BaiduYunDownload/ca3.pem"));
channel = NettyChannelBuilder.forAddress(host, port)
.sslContext(sslContext).negotiationType(NegotiationType.TLS)
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTerminated(5, TimeUnit.SECONDS);
}
public void greet(String name) {
try {
logger.info("Will try to greet " + name);
HelloRequest request = HelloRequest.newBuilder().setName(name)
.build();
HelloResponse response = blockingStub.sayHello(request);
logger.info("Greeting: " + response.getMessage());
} catch (RuntimeException e) {
logger.log(Level.WARNING, "RPC failed", e);
return;
}
}
public static void main(String[] args) throws Exception {
HelloWorldClient client = new HelloWorldClient("localhost", 50051);
try {
String user = "world";
if (args.length > 0) {
user = args[0];
}
client.greet(user);
} finally {
client.shutdown();
}
}
}
示例代码下载
http://pan.baidu.com/s/1pJFpTKR
http://pan.baidu.com/s/1o6l5Q6u