JS Websocket 卡在连接到 TCPListener 的状态 - VB.net

Posted

技术标签:

【中文标题】JS Websocket 卡在连接到 TCPListener 的状态 - VB.net【英文标题】:JS Websocket stuck in state CONNECTING to TCPListener - VB.net 【发布时间】:2015-02-04 17:00:07 【问题描述】:

注意:我发现最接近我的问题是this one,但答案是通过等待readyState为1的代理函数发送数据。这不是重复的这个问题虽然标题非常相似;我知道我的问题在于我的服务器没有将数据传回客户端,但我不知道要传递什么。

详情:

我在服务器程序中定义了一个 TCP 侦听器为 New TcpListener(ipAd, 8001),我编写了一个客户端程序为 New TcpClient() 以连接到服务器。这些程序按预期工作,一旦建立连接,客户端就准备好向服务器发送数据。

在完成客户端和服务器之后,我开始在 Web 界面上工作以充当客户端,这样我就可以从任何设备向套接字发送数据。这是 websocket 的 javascript 代码:

    console.log("Attempting to connect...");

    ws = new WebSocket('ws://192.168.0.10:8001/');

    ws.onopen = function(msg) 
        console.log('Connection successfully opened');
    ;

    ws.onmessage = function(msg) 
        console.log(msg);
    ;

    ws.onclose = function(msg) 
        console.log("Closed.");
    

    ws.error = function(err)
        console.log(err);
    

当我加载网页时,我在服务器控制台应用程序中看到已建立连接。这是输出:

GET / HTTP/1.1
Host: 192.168.0.10:8001
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-
cache
Upgrade: websocket
Origin: null
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows
 NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Accept-Enc
oding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Sec-WebSocket-Key: key_here
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

很明显,HTTP 标头是发送和接收的;但是,我的服务器(当前)没有向客户端发送任何内容,因此当我尝试从 websocket 发出 ws.send("test"); 时,我在控制台中收到错误消息:

Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.

我的问题:我需要从我的服务器发回什么来完成握手,这样我才能用ws.send();发送数据?

【问题讨论】:

***.com/a/49533457/1359764 【参考方案1】:

您需要实现 webSocket 的服务器端(或使用为您执行此操作的 webSocket 库)。这是one sample implementation in VB。还有a similar question with sample code。

webSocket 连接的工作方式如下:

    客户端使用自定义标头向服务器发出 http 请求,请求升级到 webSocket 协议

    服务器响应升级到 webSocket 是 OK 并使用随机生成的安全密钥。

    服务器发送响应,客户端收到后,双方切换为webSocket数据帧格式,以备将来数据。

    此外,还有一些必须支持的消息,例如 ping 和 pong,以支持客户端将使用的 keepalive 心跳来了解连接是否仍然存在。

请参阅 this article 以获取示例响应和 webSocket 数据帧格式的描述。

此外,浏览器默认强制执行同源限制,因此如果您尝试从浏览器连接到与 Javascript 所在网页不同的源,那么您将需要来自服务器的适当 CORS 标头开启跨域连接。


这是一个示例连接:

客户发送这个:

GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

服务器响应如下:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

然后,数据框如下所示:

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

当然,webSocket RFC 官方规范是here。

【讨论】:

您的 Mozilla 示例代码链接有效,但需要快速更改。 Dim FRRROPCODE As Byte() 需要更改为 Byte 而不是数组。此外,该代码中的“已收到”拼写错误。 尝试登录编辑它,但 Mozilla 不会接受我的凭据:\

以上是关于JS Websocket 卡在连接到 TCPListener 的状态 - VB.net的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Vue 插件连接到 WebSocket

为啥 JS WebSocket 在 sparkjava 中会卡在 CONNECTING 上?

为 Kaleido 使用 Websocket 连接时出现“连接未在 send() 上打开”错误

订阅 bitFlyer WebSocket

如何使用 cpprestsdk 设置 websocket SSL 连接?

RxJS:取消订阅嵌套订阅