【问题标题】:Closing websocket connections using libcurl when server sends close signal当服务器发送关闭信号时使用 libcurl 关闭 websocket 连接
【发布时间】:2020-10-08 15:51:53
【问题描述】:

我不是高级用户,请多多包涵。

我正在尝试使用 libcurl 实现 WebSocket 客户端,并且在连接的最后一步 - 终止之前我都很好。

一般逻辑如下:

  1. 客户端连接并发送升级请求。
  2. Websocket 服务器接受/升级并开始发送乱码。
  3. 客户端将所有乱码大小相加。
  4. 服务器在 10 秒后发送关闭信号。

到目前为止一切顺利。我没有处理传入消息的有效负载,我也不想这样做。我的资源非常有限,我不想为了检查每个有效负载并搜索关闭信号而遭受任何性能损失。

我正在使用 libcurl 的 easy 接口并使用 curl_easy_perform() 接收数据。有什么方法可以检测到关闭信号,或者 10 秒后关闭 websocket 连接?

【问题讨论】:

  • HTTP 和 WebSockets 具有 非常 不同的语义。一个是请求-响应协议,另一个是双向消息交换协议,允许推送消息……就我个人而言,我不明白 libcurl 是否适合 WebSockets,除非 WebSockets 只是一个连接到您正在尝试解决的其他问题。

标签: c websocket libcurl


【解决方案1】:

关闭信号是框架层 WebSocket 协议的一部分(请参阅 RFC 6455 部分 1.455.5.1)。

AFAIK,libcurl 本身不支持 WebSockets,只支持 HTTP(WebSocket 用于其打开握手,因此您可以使用 libcurl 伪造它)。因此,如果 libcurl 不为您处理 WebSocket 帧,您将不得不自己处理它们,即使您忽略它们的有效负载。

否则,自己设置一个 10 秒的定时器,直接关闭底层 TCP 连接,可以使用 curl_easy_getinfo(CURLINFO_ACTIVESOCKET) 从 libcurl 获取。

但是,如果服务器正在向您发送关闭信号,您应该根据Section 5.5.1 发回一个,这意味着正确地解析帧

如果端点接收到关闭帧并且之前没有发送关闭帧,则端点必须发送关闭帧作为响应。 (当发送一个关闭帧作为响应时,端点通常会回显它收到的状态代码。)它应该尽快这样做。一个端点可以延迟发送一个关闭帧,直到它的当前消息被发送(例如,如果一个分片消息的大部分已经发送,一个端点可以在发送一个关闭帧之前发送剩余的分片)。但是,不能保证已经发送 Close 帧的端点会继续处理数据。

在发送和接收关闭消息后,端点认为 WebSocket 连接已关闭,并且必须关闭底层 TCP 连接。服务器必须立即关闭底层 TCP 连接; 客户端应该等待服务器关闭连接,但可以在发送和接收到关闭消息后的任何时间关闭连接,例如,如果它没有在合理的时间内从服务器接收到 TCP 关闭时间段。

如果客户端和服务器同时发送关闭消息,则两个端点都会发送和接收关闭消息,并应认为 WebSocket 连接已关闭并关闭底层 TCP 连接。

【讨论】:

  • 我不知道这是否是另一个问题,但我正在尝试发回正确的关闭信号(完成此操作后,我还将实现 ping/pongs)。我的做法是这样的;我创建了一个这样的结构 struct websocketheader {uint32_t fin:1; uint32_t res1:1; uint32_t res2:1; uint32_t res3:1; uint32_t opcode:4; uint32_t mask:1; uint32_t payload_len:7;}; 并尝试从我的回写函数的第一个参数中填充它,比如 thisstruct websocketheader wsh; memcpy(&wsh,ptr,sizeof(struct websocketheader));但我得到了不相关的操作码。你知道我在哪里搞砸了吗?
  • 这确实应该作为新问题发布,以便您可以提供更多详细信息并显示您尝试实现的实际代码。
  • 我发了一个更详细的问题here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多