RPC是是什么
- Remote procedure call -远程过程调用 对应与本地过程调用也就是本地方法调用
- 它本身并不是一个具体的协议,而是一种调用方式。
TCP 粘包
- 什么是粘包:TCP面向字节流,没有内容分割符,可能将两条消息同时从缓存区读出来.发送两条消息 1:这是李东 2:**亚**健康终结者.接收端可能会接收到1:这是李东**亚** 2:健康终结者.如果没有正确的读取字节的话
- 怎么解决:通过分隔符or定义消息长度等.
- 直接使用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 greetings message HelloReply { string message = 1; }
- AIDL
RPC和HTTP的区别
- RPC是一种思想,比HTTP出现的早
- HTTP是一种协议
RPC的使用场景是是什么
- HTTP 浏览器->服务器
- RPC 客户端->服务器
- RPC在服务端内部集群
- Android的RPC
常见的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应该算是一种框架,包含服务发现,注册等功能