理解Autobahn与Twisted的结合

0 投票
1 回答
1259 浏览
提问于 2025-04-18 06:08

我正在尝试理解这里给出的例子:https://github.com/tavendo/AutobahnPython/tree/master/examples/twisted/wamp/basic/pubsub/basic

我写了一个脚本,目的是处理多个发布/订阅的 websocket 连接,同时还要打开一个 TCP 端口(8123)来接收控制消息。当有消息通过8123端口发送过来时,应用程序应该把这条消息广播给所有连接的订阅者。我该如何让 NotificationProtocol 或 NotificationFactory 和 websocket 进行沟通,并让 websocket 服务器广播这条消息呢?

还有一个我不太明白的地方是网址。客户端的 JavaScript 连接到网址 http://:8080/ws。那么这个 "ws" 是从哪里来的呢?

另外,能不能有人解释一下 RouterFactory、RouterSessionFactory 的作用,以及这一段:

from autobahn.wamp import types
session_factory.add( WsNotificationComponent(types.ComponentConfig(realm = "realm1" )))

我的代码如下:

import sys, time
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory
from twisted.internet.defer import inlineCallbacks
from autobahn.twisted.wamp import ApplicationSession
from autobahn.twisted.util import sleep


class NotificationProtocol(Protocol):
    def __init__(self, factory):
        self.factory = factory

    def dataReceived(self, data):
        print "received new data"

class NotificationFactory(Factory):
    protocol = NotificationProtocol

class WsNotificationComponent(ApplicationSession):
   @inlineCallbacks
   def onJoin(self, details):
      counter = 0
      while True:
         self.publish("com.myapp.topic1", "test %d" % counter )
         counter += 1
         yield sleep(1)



## we use an Autobahn utility to install the "best" available Twisted reactor
   ##
from autobahn.twisted.choosereactor import install_reactor
reactor = install_reactor()

## create a WAMP router factory
##
from autobahn.wamp.router import RouterFactory
router_factory = RouterFactory()

## create a WAMP router session factory
##
from autobahn.twisted.wamp import RouterSessionFactory
session_factory = RouterSessionFactory(router_factory)

from autobahn.wamp import types
session_factory.add( WsNotificationComponent(types.ComponentConfig(realm = "realm1" )))

from autobahn.twisted.websocket import WampWebSocketServerFactory
transport_factory = WampWebSocketServerFactory(session_factory)
transport_factory.setProtocolOptions(failByDrop = False)


from twisted.internet.endpoints import serverFromString
## start the server from an endpoint
##
server = serverFromString(reactor, "tcp:8080")
server.listen(transport_factory)

notificationFactory = NotificationFactory()
reactor.listenTCP(8123, notificationFactory)

reactor.run()

1 个回答

1

“我怎么让 NotificationProtocolNotificationFactory 和 websocket 通信,并让 websocket 服务器广播消息?”

你可以看看我在 Stack Overflow 上的另一个回答:在 twisted 中保持连接。跳到示例代码部分,把你的 websocket 逻辑模仿成“IO”逻辑,这样就能很好地适配了(你可能还想看看关于 更新的端点调用 的后续回答,那个是 twisted 核心团队的)。

“那“ws”是从哪里来的?”

Websocket 是通过重新利用 http 连接来实现的,而 http 连接本身就需要在请求中有一个特定的路径。这个“ws”路径通常会映射到一个特殊的 http 处理程序,autobahn 正在为你构建这个处理程序来处理 websocket(或者至少你的 JavaScript 是这么期待的……)。假设一切设置正确,你实际上可以在浏览器中输入那个网址,应该会返回一个关于 websocket 握手的错误信息(在我的情况下是 Expected WebSocket Headers,但我使用的是 cyclones 的 websocket,而不是 autobahn)。

附注:一个有趣的副作用是“websocket 必须有特定路径”,这意味着你可以在同一个处理程序/监听器/端口上混合使用 websocket 和普通的 http 内容。当你试图在同一个 SSL 端口上运行它们时,这特别方便,因为你可以避免需要一个代理来前置你的代码。

撰写回答