Cherrypy+Autobahn websockets在同一个p上

2024-04-28 17:37:39 发布

您现在位置:Python中文网/ 问答频道 /正文

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

例如:

  • http://localhost:8080/web到服务器静态内容(html+javascript)
  • 远景://本地主机:8080/websocketA通过类WSA处理一些WS通信
  • 远景://本地主机: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配置和运行:

^{pr2}$

此时,WebSocket服务器运行在端口8081上,但我希望在和web(8080)相同的端口上运行它。如果可能的话。。在


Tags: 端口runself服务器loopeventwebasyncio
2条回答

从字面上回答你的问题,就是说你不能用樱桃皮和高速公路。CherryPy的正常请求处理是同步的,而且它是一个线程服务器。换句话说,将一个线程专用于WebSocket连接是不可行的。CherryPy能够挂载单独的WSGI应用程序在这里没有意义,因为WSGI本质上是一个同步协议。而且WebSockets本质上是异步的。但这并不意味着你不能用不同的方式来做。在

CherryPy和ws4py

幸运的是,由于CherryPy的智能设计,它不仅限于WSGI,而且允许扩展。这个事实被CherryPy贡献者Sylvain helleguarch在nice库中使用,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和高速公路

因为1.3nginx支持WebSockets。所以你可以很容易地复用不同的后端。在

^{pr2}$

尝试使用cherrypy.tree.graft在另一个端点上挂载WSA(在cherrypy文档中称为“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

相关问题 更多 >