Websocket(Python 3.5中的ws4py)不能在Docker容器中工作

我有一个简单的Web应用程序,它使用CherryPy作为RESTful后端,ws4py作为websockets。

1) Javascript client sends a POST to Python backend 2) Python replies with a unique id 3) Javascript connects to the websocket and sends the unique id 4) Python associates the websocket client connection to the unique id 

Python websocket代码:

 class WebSocketHandler(WebSocket): def __init__(self, *args, **kw): WebSocket.__init__(self, *args, **kw) print('Connected to websocket server!') SUBSCRIBERS.add(self) def received_message(self, message): print('Websocket identified itself?') SUBSCRIBERS_WITH_ID[message.data] = self 

Python CherryPy代码:

 cherrypy.config.update({'server.socket_host': 0.0.0.0, 'server.socket_port': 8080}) cherrypy.tools.CORS = cherrypy.Tool('before_handler', CORS) WebSocketPlugin(cherrypy.engine).subscribe() cherrypy.tools.websocket = WebSocketTool() cherrypy.tree.mount( DummyAPI(), '/api/dummy', config={ '/': { 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'tools.CORS.on': True } } ) cherrypy.tree.mount( WebSocketAPI(), '/ws', config={ '/': { 'tools.websocket.on': True, 'tools.websocket.handler_cls': WebSocketHandler } } ) cherrypy.engine.start() cherrypy.engine.block() 

Javascript代码:

POST到API:

 var req = new XMLHttpRequest(); req.onload = function (e) { console.log('Response code: ' + req.responseText); result_id = req.responseText; websocketConnect(); }; req.open('POST', api_url); req.send(); 

Websocket部分:

 function websocketConnect() { websocket = new WebSocket(websocket_url); websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); websocket.send(result_id)}; 

这在我的机器上正常工作,并部署在亚马逊EC2上。 但是,当我尝试将其部署在Docker容器中时,这些websocket不起作用。

这是我的Dockerfile:

 FROM python MAINTAINER xxx RUN pip3.5 install cherrypy ws4py RUN mkdir /var/www COPY python /var/www/python EXPOSE 8080 CMD ["/usr/local/bin/python3.5", "/var/www/python/simplews.py"] 

当我从Docker运行时输出:

 sudo docker run -v /tmp/dockertmp/:/tmp/ -p 8080:8080 -i 563a51d13f59 [23/Oct/2015:10:09:00] ENGINE Bus STARTING [23/Oct/2015:10:09:00] ENGINE Starting WebSocket processing [23/Oct/2015:10:09:00] ENGINE Started monitor thread '_TimeoutMonitor'. [23/Oct/2015:10:09:00] ENGINE Started monitor thread 'Autoreloader'. [23/Oct/2015:10:09:01] ENGINE Serving on http://0.0.0.0:8080 [23/Oct/2015:10:09:01] ENGINE Bus STARTED 172.17.42.1 - - [23/Oct/2015:10:09:08] "POST ..." Connected to websocket server! 

它永远达不到JavaScript文件能够通过websocket发送数据的阶段。 Chromedebugging显示WS状态为“待定”。

但是 ,当我退出Docker中的CherryPy应用程序时,websocket消息通过:

 enter code here sudo docker run -v /tmp/dockertmp/:/tmp/ -p 8080:8080 -i 563a51d13f59 [23/Oct/2015:10:15:30] ENGINE Bus STARTING [23/Oct/2015:10:15:30] ENGINE Starting WebSocket processing [23/Oct/2015:10:15:30] ENGINE Started monitor thread '_TimeoutMonitor'. [23/Oct/2015:10:15:30] ENGINE Started monitor thread 'Autoreloader'. [23/Oct/2015:10:15:30] ENGINE Serving on http://0.0.0.0:8080 [23/Oct/2015:10:15:30] ENGINE Bus STARTED 172.17.42.1 - - [23/Oct/2015:10:15:33] "POST ..." Connected to websocket server! ^C[23/Oct/2015:10:15:35] ENGINE Keyboard Interrupt: shutting down bus [23/Oct/2015:10:15:35] ENGINE Bus STOPPING [23/Oct/2015:10:15:40] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down [23/Oct/2015:10:15:40] ENGINE Stopped thread '_TimeoutMonitor'. [23/Oct/2015:10:15:40] ENGINE Terminating WebSocket processing [23/Oct/2015:10:15:40] ENGINE Stopped thread 'Autoreloader'. [23/Oct/2015:10:15:40] ENGINE Bus STOPPED [23/Oct/2015:10:15:40] ENGINE Bus EXITING [23/Oct/2015:10:15:40] ENGINE Bus EXITED [23/Oct/2015:10:15:40] ENGINE Waiting for child threads to terminate... Websocket identified itself? 

当我没有Docker运行时输出:

 python3.5 python/simplews.py [23/Oct/2015:06:09:45] ENGINE Bus STARTING [23/Oct/2015:06:09:45] ENGINE Starting WebSocket processing [23/Oct/2015:06:09:45] ENGINE Started monitor thread '_TimeoutMonitor'. [23/Oct/2015:06:09:45] ENGINE Started monitor thread 'Autoreloader'. [23/Oct/2015:06:09:45] ENGINE Serving on http://0.0.0.0:8080 [23/Oct/2015:06:09:45] ENGINE Bus STARTED 127.0.0.1 - - [23/Oct/2015:06:09:48] "POST ..." Connected to websocket server! Websocket identified itself? 

在非Docker的情况下,websocket立即标识自己。 我无法弄清楚这一点。 WebSocket接收器线程在Docker中以某种方式卡住了?

Docker日志中的可疑部分是应用程序退出时,websocket收到的消息最终到达:

 [23/Oct/2015:10:15:40] ENGINE Waiting for child threads to terminate... Websocket identified itself? 

用threading.ThreadreplacePython多处理模块解决了这个问题。 我在POST方法处理程序中使用多处理。

以下是对实际项目的修正:

https://github.com/sevagh/youtube-audio-dl/commit/9e23ae174f8791206b934608a1d4d702b411d18e

Interesting Posts