- 什么是RPC?
- Remote procedure call -远程过程调用 对应的本地过程调用,即本地方法调用
- 它本身不是一个特定的协议,而是一种调用方式。
- TCP 粘包
- 什么是粘包:TCP面向字节流,没有内容分割符,可以同时从缓存区读取两条消息。发送两条消息 1:这是李东 2:**亚**健康终结者。接收端可接收1:这是李东**亚** 2:健康终结者。如果没有正确阅读字节
- 如何解决:通过分隔符号或定义消息长度等.
- 直接使用TCP需要定义信息边界和格式来解决这个通用问题,因此一般应用程序不会直接在TCP上建立自己的应用层协议.
- 演示demo
- 服务端
public class ServerDemo { public static void main(String[] args) throws IOException { // Create a server socket on port 1234 ServerSocket serverSocket = new ServerSocket(1234); // Wait for a client to connect Socket clientSocket = serverSocket.accept(); // Create input and output streams for the client socket BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // Read input from the client and send a response String inputLine = ""; char[] buffer = new char[5]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { inputLine = new String(buffer, 0, bytesRead); System.out.println("received "+ inputLine); out.println("Server received: " + inputLine); } // Close the streams and sockets out.close(); in.close(); clientSocket.close(); serverSocket.close(); }}
public class ClientDemo { public static void main(String[] args) throws IOException { // Create a socket to connect to the server on port 1234 Socket socket = new Socket("localhost", 1234); // Create input and output streams for the socket BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // Send a message to the server out.printf(“这是李东”); out.printf(“亚健康终结者”);// out.println("Hello, server!"); // Read the server's response String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("get response = "+inputLine); } // Close the streams and socket out.close(); in.close(); socket.close(); }}
使用RPC框架- IDL : Interface Definition Language
- Proto
syntax = “proto3”;option java_multiple_files = true;option java_package = "io.grpc.examples.helloworld";option java_outer_classname = "HelloWorldProto";option objc_class_prefix = "HLW";package helloworld;// 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 greetingsmessage HelloReply { string message = 1;}
- AIDL
- RPC和HTTP的区别
- RPC是一种比HTTP早出现的思想
- HTTP是一种协议
- HTTP 浏览器->服务器
- RPC 客户端->服务器
- 服务端内部集群RPC
- AndroidRPC
- 常见的RPC框架和实现模式
- Dubbo 基于TCP,性能更好,可定制
- gRPC 基于HTTP,兼容性更好.
- RPC的优势
- 调用本地方法就像调用本地方法一样
- gPRC
channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);HelloRequest request = HelloRequest.newBuilder().setName(message).build();HelloReply reply = stub.sayHello(request);return reply.getMessage();
- Android上的RPC
val clipboard: ClipboardManager = getContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip = ClipData.newPlainText("label", "text") clipboard.setPrimaryClip(clip)
- 使用IDL定义方法-在编译过程中可以检测到类型错误
- 总结
- 应该说,RPC和HTTP不应该是同一概念层次的东西
- RPC是一种基于HTTP的调用方式,TCP,UDP.常见的RPC应该算是一个框架,包括服务发现、注册等功能
- Build client-server applications with gRPC