java和python数据交互_Java和Python使用grpc交互

本文实现Java和Python之间通过grpc交互,只使用最基本的单项rpc。

一、Java实现grpc

使用idea新建maven项目,项目目录如下

43cdbf20c39a

image

项目的pom.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

test

grpc

1.0-SNAPSHOT

io.grpc

grpc-netty-shaded

1.15.0

io.grpc

grpc-protobuf

1.15.0

io.grpc

grpc-stub

1.15.0

kr.motd.maven

os-maven-plugin

1.5.0.Final

org.xolstice.maven.plugins

protobuf-maven-plugin

0.5.1

com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}

grpc-java

io.grpc:protoc-gen-grpc-java:1.15.0:exe:${os.detected.classifier}

src/main/resources/proto

compile

compile-custom

org.apache.maven.plugins

maven-compiler-plugin

1.8

1.8

其中proto文件如下:

helloworld.proto

syntax = "proto3";

package example;

option java_package = "com.zhj.grpc";

option java_outer_classname = "HelloWorldServiceProto";

option java_multiple_files = true;

// The greeting service definition.

service Greeter {

// Sends a greeting

rpc SayHello (HelloRequest) returns (HelloReply) {}

}

// The request message containing the user's name.

message HelloRequest {

string name = 1;

}

// The response message containing the greetings

message HelloReply {

string message = 1;

}

其中package一定要和后面Python中的package设置的值一样,,,要不。。。很难受找不出错

然后在项目的根目录下编译:

mvn compile

这时会生成相应的Java文件:

43cdbf20c39a

image

然后编写服务端代码:

package com.helloworld;

//import com

import com.zhj.grpc.GreeterGrpc;

import com.zhj.grpc.HelloReply;

import com.zhj.grpc.HelloRequest;

import io.grpc.Server;

import io.grpc.ServerBuilder;

import io.grpc.stub.StreamObserver;

import java.io.IOException;

import java.util.logging.Logger;

public class HelloWorldServer {

private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());

/* The port on which the server should run */

private int port = 50051;

private Server server;

private void start() throws IOException {

server = ServerBuilder.forPort(port)

.addService( new GreeterImpl())

.build()

.start();

logger.info("Server started, listening on " + port);

Runtime.getRuntime().addShutdownHook(new Thread() {

@Override

public void run() {

// Use stderr here since the logger may have been reset by its JVM shutdown hook.

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();

}

}

/**

* Await termination on the main thread since the grpc library uses daemon threads.

*/

private void blockUntilShutdown() throws InterruptedException {

if (server != null) {

server.awaitTermination();

}

}

/**

* Main launches the server from the command line.

*/

public static void main(String[] args) throws IOException, InterruptedException {

final HelloWorldServer server = new HelloWorldServer();

server.start();

server.blockUntilShutdown();

}

static class GreeterImpl extends GreeterGrpc.GreeterImplBase {

/** 原子Integer */

// public AtomicInteger count = new AtomicInteger(0);

@Override

public void sayHello(HelloRequest req, StreamObserver responseObserver) {

// System.out.println("call sayHello");

HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();

responseObserver.onNext(reply);

responseObserver.onCompleted();

// System.out.println(count.incrementAndGet() + Thread.currentThread().getName());

}

}

}

客户端代码:

package com.helloworld;

import com.zhj.grpc.GreeterGrpc;

import com.zhj.grpc.HelloReply;

import com.zhj.grpc.HelloRequest;

import io.grpc.ManagedChannel;

import io.grpc.ManagedChannelBuilder;

import io.grpc.StatusRuntimeException;

import java.util.concurrent.TimeUnit;

import java.util.logging.Level;

import java.util.logging.Logger;

/**

* A simple client that requests a greeting from the {@link HelloWorldServer}.

*/

public class HelloWorldClient {

private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());

private final ManagedChannel channel;

private final GreeterGrpc.GreeterBlockingStub blockingStub;

/**

* Construct client connecting to HelloWorld server at {@code host:port}.

*/

public HelloWorldClient(String host, int port) {

channel = ManagedChannelBuilder.forAddress(host, port)

.usePlaintext(true)

.build();

blockingStub = GreeterGrpc.newBlockingStub(channel);

}

public void shutdown() throws InterruptedException {

channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);

}

/**

* Say hello to server.

*/

public void greet(String name) {

logger.info("Will try to greet " + name + " ...");

HelloRequest request = HelloRequest.newBuilder().setName(name).build();

HelloReply response;

try {

response = blockingStub.sayHello(request);

} catch (StatusRuntimeException e) {

logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());

return;

}

logger.info("Greeting: " + response.getMessage());

}

/**

* Greet server. If provided, the first element of {@code args} is the name to use in the

* greeting.

*/

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();

}

}

}

然后先执行服务端,再执行客户端,客户端会收到如下信息:

九月 13, 2018 6:18:43 下午 com.helloworld.HelloWorldClient greet

信息: Will try to greet world ...

九月 13, 2018 6:18:43 下午 com.helloworld.HelloWorldClient greet

信息: Greeting: Hello world

Process finished with exit code 0

二、Python实现grpc

grpc安装:pip install grpcio

grpcbuf相关库:pip install grpcbuf

编译工具:pip install grpcio-tools

Python项目目录如下:

43cdbf20c39a

image

proto文件(与Java使用的proto文件相同):

syntax = "proto3";

package example;

// The greeting service definition.

service Greeter {

// Sends a greeting

rpc SayHello (HelloRequest) returns (HelloReply) {}

}

// The request message containing the user's name.

message HelloRequest {

string name = 1;

}

// The response message containing the greetings

message HelloReply {

string message = 1;

}

在example目录下编译:

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./helloworld.proto

会生成helloworld_pb2_grpc.py和helloworld_pb2.py文件,下面在client和sever中调用这两个文件。

服务端:

greeter_server.py

#! /usr/bin/env python

# -*- coding: utf-8 -*-

import time

import grpc

from concurrent import futures

from example import helloworld_pb2, helloworld_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24

class Greeter(helloworld_pb2_grpc.GreeterServicer):

def SayHello(self, request, context):

return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)

def serve():

server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)

server.add_insecure_port('[::]:50051')

server.start()

try:

while True:

time.sleep(_ONE_DAY_IN_SECONDS)

except KeyboardInterrupt:

server.stop(0)

if __name__ == '__main__':

serve()

客户端:

#! /usr/bin/env python

# -*- coding: utf-8 -*-

#from __future__ import print_function

import grpc

from example import helloworld_pb2, helloworld_pb2_grpc

def run():

# NOTE(gRPC Python Team): .close() is possible on a channel and should be

# used in circumstances in which the with statement does not fit the needs

# of the code.

with grpc.insecure_channel('localhost:50051') as channel:

stub = helloworld_pb2_grpc.GreeterStub(channel)

response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))

print("Greeter client received: " + response.message)

if __name__ == '__main__':

run()

先运行服务端,再运行客户端,客户端显示:

/home/zhj/.virtualenvs/test4-TkH3JH9C/bin/python /home/zhj/project/grpc/python/client/greeter_client.py

Greeter client received: Hello, you!

Process finished with exit code 0

三、Java和Pythongrpc都已实现,现在可以实现两种语言之间通信:

java-server + python-client 或者 python-server + java-client,都会显示一样的东西。

再次提示一下,Java和Python使用的proto文件一定要相同,尤其是package这一项也要相同!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值