gpt4 book ai didi

python - Cherrypy + Autobahn websocket 在同一端口上

转载 作者:太空宇宙 更新时间:2023-11-03 17:50:53 26 4
gpt4 key购买 nike

是否可以运行(挂载在cherrypy树中)autobahnn的websocket类以在相同的端口但不同的URL上运行?

例如:

  • http://localhost:8080/web服务器静态内容(html + javascript)
  • ws://localhost:8080/websocketA 通过类 WSA 处理一些 WS 通信
  • ws://localhost:8080/websocketB 通过类 WSB 来服务器一些 WS 通信

这是我的高速公路配置和运行:

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配置和运行:

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) 相同的端口上运行它。如果可以的话..

最佳答案

从字面上回答你的问题,就是说你不能用 CherryPy 和 Autobahn 来做到这一点。 CherryPy 的正常请求处理是同步的,而且它是一个线程服务器。换句话说,将线程专用于 WebSocket 连接是不可行的。 CherryPy 挂载单独 WSGI 应用程序的能力在这里没有任何意义,因为 WSGI 本质上是一个同步协议(protocol)。 WebSocket 本质上是异步的。但这并不意味着您不能以稍微不同的方式做到这一点。

CherryPy 和 ws4py

幸运的是,由于 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()

CherryPy、nginx 和 Autobahn

自 1.3 nginx支持 WebSocket。因此您可以轻松地复用不同的后端。

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;
}

}

关于python - Cherrypy + Autobahn websocket 在同一端口上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29109349/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com