JS Websocket陷入状态CONNECTING到TCPListener - VB.net

时间:2015-02-04 17:00:07

标签: javascript vb.net sockets websocket http-headers

注意:我发现的最接近的问题是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();发送数据?

1 个答案:

答案 0 :(得分:1)

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

webSocket连接的工作原理如下:

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

  2. 服务器响应升级到webSocket是正常的,并使用随机生成的安全密钥。

  3. 服务器发送响应并且客户端收到响应后,双方都会切换到webSocket数据帧格式以备将来使用。

  4. 此外,还有一些强制性消息必须支持,例如ping和pong,以支持客户端用来知道连接是否仍然存在的keepalive心跳。

  5. 请参阅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