Autobahn提供了一种有趣的订阅/发布模式,服务器端先注册一系列uri,客户端根据自己的需要订阅一些uri。用户可以通过一个uri发布信息,服务器收到后会自动转发让所有订阅了此uri的用户收到信息;当然服务器也可以主动的发布一些信息给某个指定的uri。
常用相关函数:
服务器端:
注册一个uri:
registerForPubSub(topicUri, prefixMatch=False, pubsub=3)
第二个参数表示是否被前缀匹配(不懂),第三个选项为1表示客户端只能订阅,为2表示客户端只能发布,为3表示既可订阅也可发布。
发送数据:
dispatch(topicUri, event, exclude=[])
第二个参数是发送的数据,你需要确保它能被JSON串行化,可以使用第三个参数指定某些特定的用户被排除在外(默认为空)。
js客户端:
订阅一个uri:
Session.subscribe ( topic, callback )
指定回调函数
取消订阅一个uri:
Session.unsubscribe ( topic )
发送数据:
Session.publish ( topic, event, excludeMe )
第一个参数为uri,第二个参数为发送的数据,同样要能JSON串行化,第三个参数指定是否排除自己,默认排除。
完整程序:
服务器端:
# 必须的模块
from twisted.internet import reactor
# 注意和之前的有所不同 这里WAMP表示WebSocket Application Messaging Protocol
from autobahn.wamp import exportRpc, \
WampServerFactory, \
WampServerProtocol
from autobahn.websocket import listenWS
class MyProtocol(WampServerProtocol):
# 会话初始化完成时调用的函数
def onSessionOpen(self):
print "============open============"
self.registerForPubSub("http://example.com/test1")
self.registerForPubSub("http://example.com/test2")
# 连接断开时调用的函数
def onClose(self, wasClean, code, reason):
print "close"
def publish(self):
print "publish"
test1 = "test1"
test2 = "test2"
# dispatch函数用于服务器分发数据
# 我们把不同的数据指定给不同的uri
self.factory.dispatch("http://example.com/test1", test1)
self.factory.dispatch("http://example.com/test2", test2)
if __name__ == '__main__':
factory = WampServerFactory("ws://localhost:9000")
factory.protocol = MyProtocol
listenWS(factory)
reactor.run()
js客户端:
// 第一个参数是触发该函数的uri(因为你可以给多个uri指定相同的处理函数),第二个是收到的数据内容
function refresh(topicUri, data) {
$.setHint(data);
}
$(document).ready(function() {
var sess;
// setHint是一个我自己写的函数用于显示提示消息
$.setHint("connecting");
ab.connect("ws://" + location.hostname + ":9000", function (session) {
// 连接成功后执行的函数
$.setHint();
// 之后所有的操作都通过session会话进行
sess = session;
// 订阅http://example.com/test1, 收到消息后调用refresh函数
sess.subscribe("http://example.com/test1", refresh);
},
// 连接断开后执行的函数
function (code, reason) {
sess = null;
$.setHint("failed");
}
);
// 每当复选框变化时
$("#checkbox").change(function() {
if (document.getElementById("checkbox").checked) {
// 取消订阅test1
sess.unsubscribe("http://example.com/test1");
// 订阅test2并用refresh函数处理
sess.subscribe("http://example.com/test2", refresh);
} else {
// 取消订阅test2
sess.unsubscribe("http://example.com/test2");
// 订阅test1并用refresh函数处理
sess.subscribe("http://example.com/test1", refresh);
}
});
});