一尘不染

Socket.io 1.x:仅使用WebSockets?

javascript

我们正在开发一个Web应用程序,出于各种原因,该应用程序只能在现代浏览器(IE10 +)上运行。

我们实现的功能之一是Socket.io1.x。但是,默认情况下,Socket.io客户端会尝试支持较旧的浏览器,因此它将通过长时间轮询启动连接,然后将其更新为WebSockets。鉴于我们确定浏览器支持WS,因此这是浪费时间和资源。

最终,我找到了engine.io-client的文档(Socket.io-client基于1.x分支)。这是我编写的代码, 似乎
可以正常工作。但是,我想知道这是正确的还是做错了什么:

io.connect('https://...', {
    upgrade: false,
    transports: ['websocket']
})

奇怪的是,仅将transports属性设置为websockets仅具有一个数组是不够的。我也不得不禁用upgrade。它是否正确?

更新资料

我发现了一些新发现。

随着transports设置为['websocket']只,它没有任何阉差upgrade被启用。那是正常的吗?


阅读 468

收藏
2020-05-01

共1个答案

一尘不染

socket.io发生两种“升级”。首先(在socket.io1.0+中),socket.io使用http轮询请求启动所有连接,实际上它可能仅通过http请求交换一些初始数据。然后,在那之后的某个时刻,它将尝试实际启动webSocket连接。通过发送指定upgrade: websocket报头的特定类型的http请求来完成webSocket连接,然后服务器可以适当地响应它是否支持websocket。如果服务器同意升级,则该特定的http连接将“升级”到webSocket协议。此时,客户端便知道支持webSocket,并且它停止使用轮询http请求,从而完成了upgrade对webSocket的请求。

您可以通过在客户端上执行以下操作完全阻止初始http轮询:

var socket = io({transports: ['websocket'], upgrade: false});

这将防止从您自己的合作客户端轮询连接。如果要阻止任何客户端使用轮询,则可以将其添加到服务器:

io.set('transports', ['websocket']);

但是,如果您在服务器上进行了设置,则最初与http轮询连接的socket.io客户端将根本无法工作。因此,这仅应与客户端中的正确设置相匹配,以使客户端从不开始轮询。

这将告诉两端您只想使用webSockets,而socket.io将在开始时跳过多余的http轮询。公平的警告,这样做需要webSocket支持,因此这排除了与尚不支持webSocket的IE的旧版本兼容。如果您想保持兼容性,那么只需让socket.io最初通过几个http请求就可以了。


这是有关从http升级到webSocket的协议的更多信息。

webSockets协议使用HTTP连接启动每个webSocket。这就是所有webSocket的工作方式。该HTTP连接上包含一些标头,这些标头表明浏览器将“希望”升级到webSockets协议。如果服务器支持该协议,则它会响应告诉客户端它将升级到webSocket协议,然后该套接字将从HTTP协议切换到webSocket协议。webSocket连接就是这样设计的。因此,您看到从HTTP连接开始的webSocket连接是100%正常的事实。

您可以将socket.io配置为从不使用长轮询,如果这样会使您感觉更好,但这不会改变webSocket连接仍将以HTTP连接开始,然后再升级为webSocket协议的事实,并且不会改善支持webSocket的现代浏览器中的操作效率。但是,它将这样做,以使您的连接在较旧的浏览器中无法正常工作。

2020-05-01