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的主要内容,如果未能解决你的问题,请参考以下文章
为啥 JS WebSocket 在 sparkjava 中会卡在 CONNECTING 上?
为 Kaleido 使用 Websocket 连接时出现“连接未在 send() 上打开”错误