SSL响应在两个回调上被拆分

SSL响应在两个回调上被拆分,ssl,erlang,websocket,cowboy,Ssl,Erlang,Websocket,Cowboy,我正在开发一个客户机-服务器应用程序,任务是添加对在WebSocket上运行的支持。我在服务器端使用Cowboy,并且一直在使用ErlangWebSocket客户端进行测试 事情应该是这样的: 客户端打开套接字连接并启动http握手 服务器完成http握手 客户端向服务器发送消息,服务器发送回复 客户处理回复 重复3和4次 客户端模块实现 handle_info({Transport, Socket, Data}, StateName, State) -> ... do stuff

我正在开发一个客户机-服务器应用程序,任务是添加对在WebSocket上运行的支持。我在服务器端使用Cowboy,并且一直在使用ErlangWebSocket客户端进行测试

事情应该是这样的:

  • 客户端打开套接字连接并启动http握手
  • 服务器完成http握手
  • 客户端向服务器发送消息,服务器发送回复
  • 客户处理回复
  • 重复3和4次
  • 客户端模块实现

    handle_info({Transport, Socket, Data}, StateName, State) ->
        ... do stuff with data ...
    
    当数据显示时,底层传输(gen_tcp或ssl)会调用它

    当我将客户端和服务器配置为使用
    gen\u tcp
    时,一切正常。当我改为使用
    ssl
    时,websocket握手完成,但在步骤4中,我得到一个到
    handle\u info
    的回调,该回调只包含从服务器返回的第一个字节的数据。后续回调将包含响应的其余部分

    考虑到使用gen_tcp交换的相同代码可以正常工作,我真的对这种行为感到困惑,我们还有另外两个使用
    ssl
    (但不是websockets或cowboy)构建的传输,它们同样没有表现出这种行为

    有谁能建议是什么导致数据以这种方式拆分?如果不需要的话,我宁愿不必为此编写处理

    更新:为了方便起见,我修改了客户端,使其等待两次回调,并在尝试解析之前连接两次回调的数据。这解决了问题,但仍然让我感到困惑

    但我确实注意到了几件事:

    • 第一组两个回调始终只包含一个字节
    • 该字节始终为130(0x82)

    不知道这是否相关。

    TCP中没有消息边界。你没有任何权利依赖你期望的行为。传输可以以它喜欢的任何形式提供数据,只要它以正确的顺序提供完整的数据。TCP为您提供字节流,大多数SSL库也提供字节流(尽管在较低级别上确实存在SSL记录消息)。

    这一直是我的理解,但在我参与之前,我们有三个实现(包括两个使用SSL的实现),无论是好是坏,在生产中依靠这种行为没有任何问题。如果这是一个间歇性问题,我可能会认为我们很幸运,但这一实现始终首先返回一个字节的事实似乎有一个更具体的问题。我只是想澄清一下,我不是在试图质疑TCP的本质,也不是在说其他实现是“正确的”。我只是好奇为什么他们总是表现得像以前一样,而这个新的实现总是不同的。@JohnPrice根据TCP的性质,允许它总是不同的。因为@EJP提到你不能像现在这样依赖TCP边界,所以现在只需等待两次回调就可以解决这个问题,但在某些意外情况下,或者仅仅是在Erlang的未来版本中,可能会出现中断。您应该积累二进制部分,直到您有效地拥有了至少部分工作所需的一切。需要保证的是,在同一个套接字上,不同的消息不会交错。