Python 樱桃糖&x2B;同一端口上的高速公路websockets

Python 樱桃糖&x2B;同一端口上的高速公路websockets,python,websocket,url-routing,cherrypy,autobahn,Python,Websocket,Url Routing,Cherrypy,Autobahn,是否可以运行(在cherrypy树中装载)Autobahn的websocket类以在同一端口但不同的URL上运行 例如: 服务器静态内容(html+javascript) ws://localhost:8080/websocketA通过类WSA为某些ws通信提供服务器 ws://localhost:8080/websocketB通过类WSB为某些ws通信提供服务器 这是我的高速公路配置和运行: self.loop = asyncio.new_event_loop() asyncio.set_

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

例如:

  • 服务器静态内容(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.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()
这是我的cherrypy配置和运行:

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

尝试使用
cherrypy.tree.graft
将WSA装载到不同的端点上(在cherrypy文档中称为“script\u name”)

请参见此处将WSGI应用程序作为静态文件安装在不同端点上的示例:


这里有更多的文档:

从字面上回答你的问题,就是说你不能用CherryPy和Autobahn。CherryPy的正常请求处理是同步的,而且它是一个线程服务器。换句话说,将线程专用于WebSocket连接是不可行的。CherryPy装载单独的WSGI应用程序的能力在这里毫无意义,因为WSGI本质上是一个同步协议。WebSocket本质上是异步的。但这并不意味着你不能以一种完全不同的方式去做

CherryPy和ws4py 幸运的是,由于CherryPy的智能设计,它不仅限于WSGI,而且允许扩展。CherryPy撰稿人Sylvain Hellegouarch在尼斯图书馆使用了这一事实。它具有樱桃般的集成

#!/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()

我用wss:和https:做了类似的事情,我运行了haproxy,它处理到web浏览器的连接,然后haproxy后端要么指向我的http服务器,要么指向我的web套接字路由器(高速公路)。所以,它们在后端的不同端口上,但是,它们在前端是相同的端口(haproxy找出了哪个是哪个)。非常感谢您的回答。我用Cherrypy/ws4py做了一些测试,我让它工作了:)所以你的答案是100%正确的。