从 docker 容器和节点使用 websocket 的问题

Posted

技术标签:

【中文标题】从 docker 容器和节点使用 websocket 的问题【英文标题】:Problem using websockets from docker container and node 【发布时间】:2019-07-17 19:08:22 【问题描述】:

我有从 docker 容器运行的节点,我尝试编写一些 websocket 示例。但我遇到了下一个问题:

root@7cd5a41c8eea:/application/webSocketEx# node
> var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
ReferenceError: WebSocket is not defined
> const WebSocket = require('ws');
undefined
> var ws = new WebSocket("ws://www.websocket.org");
undefined
>  Error: Unexpected server response: 404

    at ClientRequest.req.on (/application/webSocketEx/node_modules/ws/lib/websocket.js:579:7)
    at ClientRequest.emit (events.js:182:13)
    at ClientRequest.EventEmitter.emit (domain.js:460:23)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:555:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
    at Socket.socketOnData (_http_client.js:441:20)
    at Socket.emit (events.js:182:13)
    at Socket.EventEmitter.emit (domain.js:460:23)
    at addChunk (_stream_readable.js:283:12)
    at readableAddChunk (_stream_readable.js:264:11)
  domainEmitter:
   WebSocket 
     domain:
      Domain 
        domain: null,
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        members: [] ,
     _events: ,
     _eventsCount: 0,
     _maxListeners: undefined,
     readyState: 2,
     protocol: '',
     _binaryType: 'nodebuffer',
     _closeFrameReceived: false,
     _closeFrameSent: false,
     _closeMessage: '',
     _closeTimer: null,
     _closeCode: 1006,
     _extensions: ,
     _receiver: null,
     _sender: null,
     _socket: null,
     _bufferedAmount: 0,
     _isServer: false,
     _redirects: 0,
     url: 'ws://www.websocket.org',
     _req:
      ClientRequest 
        domain: [Domain],
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: true,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Socket],
        connection: [Socket],
        _header:
         'GET / HTTP/1.1\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: 2c4HivAKv2OJ6rO7qYyaNA==\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\nHost: www.websocket.org\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: undefined,
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path: '/',
        _ended: false,
        res: [IncomingMessage],
        aborted: 1563389938612,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: [HTTPParser],
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object]  ,
  domain:
   Domain 
     domain: null,
     _events:
       removeListener: [Function: updateExceptionCapture],
        newListener: [Function: updateExceptionCapture],
        error: [Function: debugDomainError] ,
     _eventsCount: 3,
     _maxListeners: undefined,
     members: [] ,
  domainThrown: false 
> 

我是否缺少从 docker 容器和节点使用 websockets 的配置参数?我已经使用 npm install ws 安装了 ws。我感觉我需要为 docker 容器打开一个端口,但我不明白是哪个。

谢谢

【问题讨论】:

【参考方案1】:

Docker 容器在它们自己的子网上运行,因此它们不能从它访问任何其他主机。您需要将 docker 子网显式更改为您的主机子网(桥接网络),一旦您的 docker 容器与主机位于同一网络上,您的容器将能够访问互联网。

你需要实现这样的东西。

docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 dockernet

version: '2' services: web: image: some/image networks: - dockernet networks: dockernet: external: true

有关详细信息,您可以在此处阅读针对您的特定用例的文档:

https://docs.docker.com/network/network-tutorial-standalone/

https://technology.amis.nl/2018/08/18/docker-host-and-bridged-networking-running-library-httpd-on-different-ports/

【讨论】:

以上是关于从 docker 容器和节点使用 websocket 的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 应用程序中使用 docker 容器启动运行 websockets

从 docker 容器调试节点 (>=6.3)

通过 nginx 或 traefik 通过 html 网页访问 docker 容器 websocket?

从docker容器内的节点服务器访问ubuntu localhost

从节点映像运行 docker 容器时找不到 Npm

运维之我的docker-swarm集群中删除节点和服务