【问题标题】:How to know which websocket version the client uses?如何知道客户端使用哪个 websocket 版本?
【发布时间】:2012-03-29 15:56:30
【问题描述】:

我用 python 编写了一个(不那么)简单的 websocket 服务器,它监听一个端口,执行握手,然后向客户端发送一个包含数字的消息序列(间隔随机间隔)。

我写了一个 javascript 客户端并在 Chrome 和 Safari 下进行了测试。我发现 Chrome 和 Safari 使用不同的 WebSocket 版本。例如,Chrome 使用 Sec-WebSocket-Key(并期望 Sec-WebSocket-Accept),而 Safari 则在标头之后发送 Sec-WebSocket-Key1、Sec-WebSocket-Key2 和一堆 8 个字节。

我在服务器中实现了一个握手功能,它检测所需的握手类型并执行它。这个问题解决了。 websocket 已从 Chrome 或 Safari(OSX、Windows 和 IOS5 版本)正确打开。

但我还有另一个问题。显然,Safari 发送并期待由 0x00 和 0xFF 分隔的消息,而 Chrome 发送并期待带框和屏蔽的数据(使用较新版本的 websocket 规范)。

我想要一个服务器,它可以根据客户的期望进行调整。我的问题是,我怎样才能提前知道数据是否必须以帧或 0x00,0xFF 分隔发送?

我想我可以假设,如果握手协议基于 Key1 和 Key2,则客户端是 Safari,然后使用 0x00 0xFF 来分隔数据,而如果它使用 Sec-WebSocket-Key,则客户端是 Chrome,并且然后使用框架数据。但是我对这个解决方案并不满意,因为它不是通用的。想法?

【问题讨论】:

    标签: google-chrome safari version websocket


    【解决方案1】:

    Safari(桌面版和移动版)使用的hixie-76 协议变体和Chrome 等使用的RFC 6455 都有已发布的标准。

    您可以使用请求的握手类型来决定客户端使用的协议版本、消息读取时将存在什么帧以及您应该在消息写入时使用什么帧。

    【讨论】:

    • 感谢您的链接。如果我理解正确,没有“WebSocket-Version”或类似的标头,然后我应该编写临时代码来手动检测使用的版本,对吧?
    • 没错。 (在后来的 RFC 草案中有一个版本标头,但在 Chrome 和 Safari 中都没有合适的标头。)我有一个简单的 websocket 服务器,它使用 Sec-WebSocket-Key1 标头来推断 hixie-76(Safari)和Sec-WebSocket-Key 标头来推断 RFC 6455 (Chrome)。
    • 这是不正确的。对于 >= Hybi.10 的任何内容,标头由 Chrome、Firefox、WebKit Nightly、IE10 .. Sec-WebSocket-Version 发送。他们确实发送了 8 或 13。虽然旧 Hixie-76 不存在此标头 .. 但该已弃用版本中唯一仍在使用的是 Safari。 Webkit Nightly 有 RFC6455。看看:autobahn.ws/testsuite/reports/clients/index.html 点击不同浏览器的案例 1.1.1 并向下滚动到 WebSocket 握手。免责声明:我是 Autobahn 的作者,为 Tavendo 工作。
    • @oberstet,最初的问题是关于如何编写一个可以与 Chrome 和 Safari(桌面和移动)对话的 websocket 服务器。我认为许多 iOS 浏览器仍然使用 Hixie-76。你是说iOS现在使用Hybi-10+?如果是这样,您知道这是从哪个版本开始的吗? (我查看了您的网页,但这些信息并不是很明显。)
    • 不,WebKit Nightly(截至 2012 年 3 月)使用 RFC6455。我不知道是否以及何时进入 iOS。
    【解决方案2】:

    简单:WebSockets 只有一个版本。其余为草稿。现在 RFC 已经发布,官方建议您不要实施其他任何东西。最新版本的 Firefox 和 Chrome 都实现了 RFC 版本,并且它们会自动更新。这些草案很快就会被客户停止使用,因此即使是为了获得更多的互操作性,也没有必要尝试实施它们。

    它们不再相关,并且添加了杂乱无章。任何浏览器供应商都不打算继续支持这些草案。事实上,Mozilla 一直等到规范才取消其 websocket 对象的前缀。同样,浏览器供应商很清楚,为草稿编写的任何应用程序都应该是演示,而不是生产代码,并且不期望他们支持草稿服务器就像支持草稿客户端代码一样。

    所以,坚持一个规范,忘记草稿的早期实施。

    【讨论】:

    • 如果您想在移动设备上运行,这不是一个真正的选择。
    • 同意@kybernetikos。在移动浏览器推出采用最新协议的版本之前,您必须同时支持旧协议和当前协议。
    【解决方案3】:

    为了回答您最初的问题,因为我有同样的需要,我发现 window.WebSocket.CLOSED 在最新的实现中等于 3,而在较旧的实现中,它等于 2(以 Android 原生浏览器为例)。

    所以我现在检测是否支持最新的 WebSocket 协议的测试是:

    if('WebSocket' in window
        &&'function' === typeof window.WebSocket
        &&3 === window.WebSocket.CLOSED) {
    // hurra !
    }
    

    我在 Chrome、Firefox(成功)和 Android 浏览器(失败)上对其进行了测试。希望它能帮助那里的一些人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-31
      • 2019-07-08
      • 1970-01-01
      • 2016-02-19
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多