Autobahn提供了远程调用模式(RPC = Remote Procedure Calls),服务器写好供调用的函数并注册一个uri,客户端调用函数时对应的代码就会在服务器上跑一遍并返回结果给客户端。
常用相关函数:
服务器端:
注册一个服务object用于rpc:
registerForRpc(obj, baseUri='')
obj指定执行代码时的self,baseuri为客户端call时的前缀。这个函数将会把obj所属类中所有带@exportRpc的方法提供给客户端调用。
实际执行的代码相当于obj.(realUri-baseUri)
注册一个obj和其中的一个方法:
registerMethodForRpc(uri, obj, proc)
注册一个全局函数:
registerProcedureForRpc(uri, proc)
js客户端:
远程调用函数:
Session.call ( method, ... )
method是一个uri,用它减去服务器中注册的baseUri即为调用的方法名,后跟变长参数列表。
如需注册回调函数,可以使用then()方法分别给执行成功和失败注册。类似如下代码:
sess.call("http://example.com#test", 1, 2, 3).then(function(res){}, function(error) {})
完整程序:
服务器端:
from twisted.internet import reactor
from autobahn.wamp import exportRpc, \
WampServerFactory, \
WampServerProtocol
from autobahn.websocket import listenWS
class MyProtocol(WampServerProtocol):
def onSessionOpen(self):
# 因为输出的函数都在本类里,故第一个参数为self
# 否则需要实例化一个含输出函数的类做为参数
self.registerForRpc(self, "http://example.com/rpc#")
# @exportRpc说明此函数会被输出
@exportRpc
def login(self, username):
print "login"
@exportRpc
def new(self, username, roomname, size):
print "new"
@exportRpc
def join(self, username, roomname):
print "join"
@exportRpc
def exit(self, username, roomname):
print "exit"
if __name__ == '__main__':
factory = WampServerFactory("ws://localhost:9000")
factory.protocol = MyProtocol
listenWS(factory)
reactor.run()
js客户端:
$(document).ready(function() {
var username = $.cookie("username");
var sess;
// setHint是一个我自己写的函数用于显示提示消息
$.setHint("connecting");
ab.connect("ws://" + location.hostname + ":9000", function (session) {
// 连接成功后执行的函数
$.setHint();
sess = session;
// 远程调用,可以看到这里的uri比服务器中注册的http://example.com/rpc多了login,故调用的是login函数,后跟变长参数列表
// .then指定回调函数
sess.call("http://example.com/rpc#login", username).then(
function (res) {
// 执行成功后的函数,res为返回值
},
function (error) {
// 执行失败的函数,可以通过error.desc查看具体原因
$.setHint("failed");
}
);
},
function (code, reason) {
// 连接断开后执行的函数
sess = null;
$.setHint("failed");
}
);
$("#new").click(function() {
// 远程调用new函数,后跟三个参数
sess.call("http://example.com/rpc#new", username, username, 5).then(
function (res) {
// 执行成功后
location = "game.html"
},
function (error) {
// 执行失败后
$.setHint("newmfailed");
}
);
});
});