关于node.js:Linux Bash:如何以客户端身份打开Websocket连接

Linux Bash: How to open a websocket connection as client

我已经创建了一个提供Web套接字服务器的Node.JS应用程序(使用npm ws)。 该websocket等待直到建立连接。 一旦连接命中服务器,Websocket将执行作业。 作业完成后,将通过套接字发送一条消息,然后关闭套接字。
该套接字按预期方式工作; 已经使用另一个Node.JS脚本对其进行了测试。

如何仅使用linux命令行工具连接到Web套接字?
我已经按照此处所述尝试卷曲。 但是,我找不到如何正确连接到运行在localhost:8088 / socket /的websocket的方法。

编辑:
我的问题已被确定可能与另一个问题重复。 但是,链接的问题仅询问是否有解决卷曲的方法。 我很高兴看到任何适用于bash的解决方案。 另外,链接问题的答案是使用autobahn.ws的javascript文件


我的工具websocat是专门为此设计的。

1
websocat ws://your_server/url

您可以与服务器连接并交换数据。默认情况下,每行都将成为WebSocket文本消息,反之亦然。

在Linux上,使用readline玩起来更舒服:

1
rlwrap websocat ws://your_server/url.

它不是唯一的CLI Websocket客户端。也有" ws"和" wscat"项目。


从这里尝试这个:如何打WebSocket端点?

1
$ curl -i -N -H"Connection: Upgrade" -H"Upgrade: websocket" -H"Host: echo.websocket.org" -H"Origin: http://www.websocket.org" http://echo.websocket.org

他从这里获得的信息:http://www.thenerdary.net/post/24889968081/debugging-websockets-with-curl

将来引用此网站的内容:

Those flags say:

  • Return headers in the output
  • Don’t buffer the response
  • Set a header that this connection needs to upgrade from HTTP to something else
  • Set a header that this connection needs to upgrade to a WebSocket connection
  • Set a header to define the host (required by later WebSocket standards)
  • Set a header to define the origin of the request (required by later WebSocket standards)
  • 如果网络套接字正在运行,则应返回以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $ curl -i -N -H"Connection: Upgrade" -H"Upgrade: websocket" -H"Host: echo.websocket.org" -H"Origin:http://www.websocket.org" http://echo.websocket.org
    HTTP/1.1 101 Web Socket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    WebSocket-Origin: http://www.websocket.org
    WebSocket-Location: ws://echo.websocket.org/
    Server: Kaazing Gateway
    Date: Mon, 11 Jun 2012 16:34:46 GMT
    Access-Control-Allow-Origin: http://www.websocket.org
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: content-type
    Access-Control-Allow-Headers: authorization
    Access-Control-Allow-Headers: x-websocket-extensions
    Access-Control-Allow-Headers: x-websocket-version
    Access-Control-Allow-Headers: x-websocket-protocol


    vi答案提供了非常有用的工具。 websocat非常易于使用。

    我只想使用bash内置函数执行此操作。我认为对其他人更好地理解协议可能很有用。

    Websocket协议握手很容易。

    要在bash中打开tcp通道,我们可以使用:

    1
    2
    3
    wshost=echo.websocket.org
    wsport=80
    exec 3<>/dev/tcp/${wshost}/${wsport}

    然后,我们可以使用文件描述符&3向该tcp连接读取和写入数据。

    首先让我们打开一个读取通道:

    1
    2
    3
    CR=$(echo -en"\
    "
    )
    while read <&3; do echo"WS MSG:[${REPLY//$CR/}]"; done &

    我们实际上不需要替换回车字节\
    ,但是如果不需要,则终端输出很奇怪。

    每个websocket服务器实施都可能需要特定的详细信息。 websocket.org在结束行之前需要Origin标头和\
    字节。

    然后我们可以开始连接upgrade

    1
    2
    3
    4
    5
    6
    7
    8
    echo -e"GET / HTTP/1.1\
    Host: ${wshost}\
    Connection: Upgrade\
    Upgrade: websocket\
    Sec-WebSocket-Accept: $(echo -n"somekey"|base64)\
    Origin: http://www.websocket.org\
    \
    "
    >&3

    立即我们看到ws升级输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ WS MSG:[HTTP/1.1 101 Web Socket Protocol Handshake]
    WS MSG:[Access-Control-Allow-Credentials: true]
    WS MSG:[Access-Control-Allow-Headers: content-type]
    WS MSG:[Access-Control-Allow-Headers: authorization]
    WS MSG:[Access-Control-Allow-Headers: x-websocket-extensions]
    WS MSG:[Access-Control-Allow-Headers: x-websocket-version]
    WS MSG:[Access-Control-Allow-Headers: x-websocket-protocol]
    WS MSG:[Access-Control-Allow-Origin: http://www.websocket.org]
    WS MSG:[Connection: Upgrade]
    WS MSG:[Date: Thu, 29 Oct 2020 15:08:01 GMT]
    WS MSG:[Sec-WebSocket-Accept: eXT5yQBZ/TOhFBUi6nLY8cfzs1s=]
    WS MSG:[Server: Kaazing Gateway]
    WS MSG:[Upgrade: websocket]
    WS MSG:[]

    您看到Sec-WebSocket-Accept标头吗?服务器按照RFC 6455中的说明解决该问题。我们可以使用以下方法进行计算:

    1
    2
    3
    $ echo -n"$(echo -n"somekey" | base64)258EAFA5-E914-47DA-95CA-C5AB0DC85B11" |
       sha1sum | cut -d"" -f1 | xxd --ps -r  | base64
    eXT5yQBZ/TOhFBUi6nLY8cfzs1s=

    我知道... cutxxdbase64sha1sum不是内置的,但是此验证步骤仅供参考。

    握手完成后,我们的tcp连接现在已升级为websocket连接。

    现在是困难的部分。

    我们需要发送数据。我们可以在RFC6455的第5部分中学习如何做。

    a client MUST mask all frames that it sends to the server (see Section 5.3 for further details)

    The server MUST close the connection upon receiving a frame that is not masked

    阅读RFC 5.2节,了解如何屏蔽数据。

    RFC甚至提供了一种用于数据屏蔽的科学技术:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
      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 ...                |
     +---------------------------------------------------------------+

    我想编写一个bash函数来掩盖ws数据,但是我现在不能这样做。我稍后会更新这篇文章。