是否可以运行(在cherrypy tree中挂载)autobahnn的websocket类在相同的端口上运行但不同的URL?
例如:
这是我的高速公路配置&运行:
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
factory = WebSocketServerFactory("ws://0.0.0.0:8081", debug = False)
factory.protocol = WSA.SocketClient
coro = self.loop.create_server(factory, "0.0.0.0", 8081)
server = self.loop.run_until_complete(coro)
self.loop.run_forever()
这是我的樱桃配置&运行:
cherrypy.config.update({
'server.socket_host' : '0.0.0.0',
'server.socket_port' : 80,
})
cherrypy.tree.mount(WebApi.Web(), '/web', {
'/': {
"tools.staticdir.on": True,
"tools.staticdir.root": os.path.dirname(os.path.abspath(__file__)),
"tools.staticdir.dir": "Web",
"tools.staticdir.index": "index.html"
}
})
cherrypy.engine.start()
此时,WebSocket服务器在端口8081上运行,但我想在与web(8080)相同的端口上运行它。如果有可能..
答案 0 :(得分:1)
从字面上回答你的问题,就是说你不能用CherryPy和Autobahn来做。 CherryPy的正常请求处理是同步的,而且它是一个线程服务器。换句话说,将线程专用于WebSocket连接是不可行的。 CherryPy在这里安装单独的WSGI应用程序的能力毫无意义,因为WSGI本质上是一种同步协议。 WebSockets本质上是异步的。但这并不能让你以不同的方式做到这一点。
幸运的是,由于CherryPy的智能设计,它不仅限于WSGI并允许扩展。这个事实被CherryPy撰稿人Sylvain Hellegouarch ws4py用于很好的图书馆。它有CherryPy集成。
#!/usr/bin/env python3
import cherrypy
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import WebSocket
class Ws:
@cherrypy.expose
def a(self):
'''WebSocket upgrade method.
Method must exist for ``WebSocketTool`` to work, 404 returned otherwise.
'''
@cherrypy.expose
def b(self):
pass
class HandlerA(WebSocket):
def received_message(self, message):
self.send('"A" is my reply')
class HandlerB(WebSocket):
def received_message(self, message):
self.send('"B" is my reply')
class App:
@cherrypy.expose
def index(self):
return '''<!DOCTYPE html>
<html>
<body>
<table cellspacing='10'>
<tr>
<td id='a'></td>
<td id='b'></td>
</tr>
</table>
<script type='application/javascript'>
var wsA = new WebSocket('ws://127.0.0.1:8080/websocket/a');
wsA.onmessage = function(event)
{
document.getElementById('a').innerHTML += event.data + '<br/>';
};
var wsB = new WebSocket('ws://127.0.0.1:8080/websocket/b');
wsB.onmessage = function(event)
{
document.getElementById('b').innerHTML += event.data + '<br/>';
};
setInterval(function()
{
wsA.send('foo');
wsB.send('bar');
}, 1000);
</script>
</body>
</html>
'''
if __name__ == '__main__':
cherrypy.config.update({
'server.socket_host' : '127.0.0.1',
'server.socket_port' : 8080,
'server.thread_pool' : 8
})
cherrypy.tools.websocket = WebSocketTool()
WebSocketPlugin(cherrypy.engine).subscribe()
cherrypy.tree.mount(Ws(), '/websocket', {
'/a' : {
'tools.websocket.on' : True,
'tools.websocket.handler_cls' : HandlerA
},
'/b' : {
'tools.websocket.on' : True,
'tools.websocket.handler_cls' : HandlerB
}
})
cherrypy.tree.mount(App(), '/')
cherrypy.engine.signals.subscribe()
cherrypy.engine.start()
cherrypy.engine.block()
由于1.3 nginx支持WebSockets。因此,您可以轻松地复用不同的后端。
server {
listen 80;
server_name localhost;
location /web {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /websocket {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
答案 1 :(得分:0)
尝试使用cherrypy.tree.graft
在不同的端点上安装WSA(在cherrypy docs中称为“script_name”)。
请参阅此处的示例,将WSGI应用程序安装在不同的端点上作为静态文件:http://rhodesmill.org/brandon/2011/wsgi-under-cherrypy/
此处有更多文档:http://cherrypy.readthedocs.org/en/latest/advanced.html#host-a-foreign-wsgi-application-in-cherrypy