当前位置: 首页 > 工具软件 > Drogon > 使用案例 >

Drogon中WebSocket部分源码梳理

浦墨竹
2023-12-01

Drogon虽然是后端的框架,但也能实现网络客户端的相关功能。虽然在类名定义上有明确的Client的字样但对于其中设计思路一直没有梳理清楚,为什么一块完整的业务要拆成两部分?终于在看了几遍之后觉得找对了方向,故做个记录。
WebSocketClientImpl是WebSocketClient的接口实现类,由于websockect整个连接过程的发起端在客户端,所以该接口中做了TCPClient连接的创建,并发起TCP连接,借助该连接做了如下处理:

  1. 组装ws协议升级的http请求,并发送给后端服务;
  2. 接收服务的响应,做初步解析,若含同意升级的字段,则开始WebScokect协议数据的解析处理,至此websockect连接也就建立完成。也是在该处创建WebSockectConnection对象。

建立连接之后便是数据的收发、解析和连接状态的维护,这些无论是ws的客户端和服务端都是需要的。所以我们看到了WebSockectConnectionImp中做的事情:

  1. 数据的收发;
  2. ws协议数据解析,将解析后的数据回调给wsclient等上层业务;
  3. ws心跳状态的维护。

服务端对协议升级的请求处理上则较为简单只要创建websockectconnection准备收发数据,没有类似websocketserver的封装。所以在HttpServer中可以看到如下代码:

// if (requestParser->firstReq() &&
//     如果是websockect的连接请求,创建webconnection的数据,处理后续的ws数据
//     isWebSocket(requestParser->requestImpl()))
// {
//     auto wsConn =
//         std::make_shared<WebSocketConnectionImpl>(conn);

当然后端对ws处理的复杂之处在于协议转发和业务处理,所重头在router和controller。
另外,由于HttpServer本身具有TCPconnect数据回调处理的能力,所以数据回调接收部分没有作为公共业务放到WebSockectConnection中,这也是WebSockectClient中有TCPClient成员,做tcp数据回调,然后将数据转发给WebSockectConnection对象原因,服务端和客户端的职责对等,共有的业务逻辑独立封装,其他的差异业务各自封装。WebSockectConnection在ws数据解析完成后回调给client或sever对象。
TCPClient和TCP的Connection也是这个思路。类似的思路库中还有很多,比如HttpRequest与HttpRequestParser,HttpResponse和HttpResponseParser,对请求端而言,复杂之处在于响应数据的解析,所以有ResponseParser,服务端的重难点在于请求的解析,所以有了RuquestParser。复杂的单端用的业务都是单拎出来封装,更容易维护。

 类似资料: