gRPC 服务端初始化以及如何和客户端建立连接
8. Server 初始化
下面是 GreeterServer 使用 ServerBuilder 构造一个 gRPC 服务端例子
- • AddListeningPort 添加服务器地址
- • RegisterService 注册服务实例
- • BuildAndStart() 构造以及运行服务端
void RunServer(uint16_t port) { std::string server_address = absl::StrFormat("0.0.0.0:%d", port); GreeterServiceImpl service; grpc::EnableDefaultHealthCheckService(true); grpc::reflection::InitProtoReflectionServerBuilderPlugin(); ServerBuilder builder; // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); // Register "service" as the instance through which we'll communicate with // clients. In this case it corresponds to an *synchronous* service. builder.RegisterService(&service); // Finally assemble the server. std::unique_ptr<Server> server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; // Wait for the server to shutdown. Note that some other thread must be // responsible for shutting down the server for this call to ever return. server->Wait(); }
使用 ServerBuilder::BuildAndStart() 函数构造一个 Server 出来,并且开始运行,其调用如下
构造的 Server 静态总体数据结构如下:
- • server_ 指向的是 grpc_core::Server 对象
- • grpc_core::Server::listener_states_ 是 list 容器,保存 NewChttp2ServerListener 对象
- • NewChttp2ServerListener::tcp_server_ 指向的是 grpc_tcp_server() 对象
- • grpc_tcp_server 和 client 端类似,也是依赖 PosixEventEngine
调用 Server::Start() 函数时,设置 socket 可读(有连接到来)时的回调函数
AsyncConnectionAcceptor::handle_ 被注册到 epoll 中
9. Server 处理 accept
服务器 socket 可读时,调用 accept 和客户端建立 TCP 连接
DoHandleshake() 函数是 Server 和 Client 做握手建立
握手完成后通过回调调用 OnHandshakeDone() 开始读 Client 发送的数据