理解Autobahn与Twisted的结合
我正在尝试理解这里给出的例子: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 个回答
“我怎么让 NotificationProtocol
或 NotificationFactory
和 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 端口上运行它们时,这特别方便,因为你可以避免需要一个代理来前置你的代码。