英文好的 来这里 https://grpc.io/docs/ 因为中文资料中很多链接都是不通的,步骤也不太对 所以我是两个一起看的,不看怎么知道中文资料坑多呢?。英文资料比中文资料靠谱多了,如果你按这个所谓的权威中文走,会走很多弯路,内心大骂坑太多,但其实人家英文上都很好的说明解释了,步骤简单明确。
gRPC 是一个高性能、开源和通用的 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 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。
先跑一遍java的demo试一下 因为跑android和ios之前 也要先搭个服务器,所以先用java跑个客户端和服务器 下边这些命令依次执行 是用来下载demo代码 和编译client和server 还有 运行client和sever的
(https://grpc.io/docs/quickstart/java.html 看了很多资料 这个资料是最靠谱 最容易操作的,那个中文版的 真的太啰嗦了,木有重点)
#这里一定要选分支,不然 默认的master分支 一般用户都会报错的 官方的readme上说 没贡献的开发者是不给用master的
$ git clone -b v1.17.0 https://github.com/grpc/grpc-java
$ cd grpc-java/examples
$ ./gradlew installDist
$ ./build/install/examples/bin/hello-world-server
$ ./build/install/examples/bin/hello-world-client
到这里 就算运行起来了,下面说的是改proto 如果你只是做client 你可以直接跳到android和ios的client的操作步骤上去,server的启动准备算是finish了
改一下服务协议,运行效果看一下 来体会一下通信过程,这个搞懂了原理的话,基本可以上手写个简单的聊天或者广播程序了。
src/main/proto/helloworld.proto 这个是通讯协议,改这个文件
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (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;
}
src/main/java/io/grpc/examples/helloworld/HelloWorldServer.java 这个是服务端代码 改下
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
@Override
public void sayHelloAgain(HelloRequest req, StreamObserver responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello again " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
...
src/main/java/io/grpc/examples/helloworld/HelloWorldClient.java 这个是客户端代码 改下
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());
try {
response = blockingStub.sayHelloAgain(request);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.info("Greeting: " + response.getMessage());
}
改好了通信协议,server和client,就可以编译运行了
$ ./gradlew installDist
$ ./build/install/examples/bin/hello-world-server
$ ./build/install/examples/bin/hello-world-client
你如果把java server和client运行完了 会发现文件夹里有android,对滴,还是这个项目,到android文件夹里去编译运行android就好了
$ cd android/helloworld
$ ../../gradlew installDebug
改个代码看一下(server和proto的代码改动请参照上文,这里只说一下android代码的改动)
app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java
try {
HelloRequest message = HelloRequest.newBuilder().setName(mMessage).build();
HelloReply reply = stub.sayHello(message);
reply = stub.sayHelloAgain(message);
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
pw.flush();
return "Failed... : " + System.lineSeparator() + sw;
}
利用之前的java服务器来测试oc的客户端 也可以搭个C++的服务器 都一样的 没影响 protocol buffer是字节流,平台无关的
先拉demo代码 跑起来 跟前面的server通个信(这个demo里对应的server是c++的 可以用这个server 也可以用前面run起来的server)
$ git clone --recursive -b v1.17.1 https://github.com/grpc/grpc.git
$ cd grpc
$ make
$ [sudo] make install
$ brew tap grpc/grpc
$ brew install protobuf
$ cd examples/objective-c/helloworld
$ pod install
$ open HelloWorld.xcworkspace
刚才改过java的protocol和server 现在改一下ios代码看下效果 examples/objective-c/helloworld/main.m
int main(int argc, char * argv[]) {
@autoreleasepool {
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
[GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress];
HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress];
HLWHelloRequest *request = [HLWHelloRequest message];
request.name = @"Objective-C";
[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
NSLog(@"%@", response.message);
}];
[client sayHelloAgainWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
NSLog(@"%@", response.message);
}];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
如果不用之前的java的server 也可以用这个demo里的c++server
$ cd examples/cpp/helloworld
$ make
$ ./greeter_server &
那改ios代码的时候 就要记得改对应的proto和c++server代码
examples/protos/helloworld.proto
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (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;
}
examples/cpp/helloworld/greeter_server.cc
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello again ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
改了server 就编译运行一下c++的server
$ pkill greeter_server
$ make
$ ./greeter_server &
执行命令过程中 肯定会遇到很多failed 这里整理了一些 我遇到的
$ ./gradlew installDist 执行这个 编译的时候报错 Could not find io.grpc:grpc-protobuf:1.18.0-SNAPSHOT.
解决办法:https://github.com/grpc/grpc-java/issues/5083
意思就是说,你不能拉master分支 要去拉release分支,如果已经clone了 就去切分支就好了(但不能切.x分支 因为也会找不到对应的.x的maven库,要去切定版)
$ ./gradlew installDist 执行这个 编译的时候报错 Could not resolve com.jcraft:jsch:0.1.54.
解决办法:检查一下你的npm的Registry源,切到淘宝上去就好了
$ ./gradlew installDist 执行这个 编译的时候报错 Execution failed for task ‘:grpc-compiler:compileJava_pluginExecutableJava_pluginCpp’.
解决办法:c++的编译问题,在pom文件中加一些属性和依赖
com.google.guava
guava
23.6-jre
org.apache.httpcomponents
httpcore
4.4.8
profile1
com.SomeClass
profile2
com.SomeOtherClass
org.springframework.boot
spring-boot-maven-plugin
1.5.2.RELEASE
repackage
${spring.boot.mainclass}
...
https://111qqz.com/2018/10/java-grpc-踩坑记录/
也可以看看这个坑友的 他的坑和我遇到的坑不一样