Для иллюстрации основ использования механизма RPC рассмотрим пример, в котором для обработки списка чисел используется класс JsonService; в примере вычисляется сумма чисел или сумма квадратов чисел. Клиент определяет SMD, в котором описываются два метода,
sum и sumOfSquares, каждый из которых принимает список чисел:
<html>
<head>
<title>Fun with JSON RPC!</title>
<script type="text/javascript"
src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js"
djConfig="isDebug:true">
</script>
<script type="text/javascript">
dojo.require("dojo.rpc.JsonService");
dojo.addOnLoad(function() {
//создать описание smd в виде литерала объекта...
var o = {
"serviceType": "JSONRPC",
"serviceURL": "/",
"methods":[
{
"name": "sum",
"parameters":[{name : "list"}]
},
{
"name": "sumOfSquares",
"parameters":[{name : "list"}]
}
]
}
//создать экземпляр службы
var rpcObject = new dojo.rpc.JsonService(o);
//вызвать службу и использовать объект Deferred
//для добавления функций обратного вызова
var sum = rpcObject.sum([4,8,15,16,23,42]);
sum.addCallback(function(response) {
console.log("the answer is ", response);
});
//добавить дополнительные функции обратного вызова
//и обработки ошибок.
//функция sumOfSquares вызывается точно так же...
});
</script>
</head>
(body)
(/body)
</html>
Надеюсь, вы поняли, что при большом количестве методов, взаимодействующих с сервером стандартным способом, общая простота вызовов RPC на стороне клиента после их настройки значительно облегчает структуру приложения. Элегантность использования функции dojo.rpc.JsonService в значительной степени обусловлена тем, что она возвращает объект Deferred, благодаря чему имеется возможность добавлять функции обратного вызова и функции обработки ошибок.
На тот случай, если вы пожелаете опробовать этот пример в действии, ниже приводится сценарий службы. Для простоты примера этот сценарий не использует библиотеку работы с форматом JSON, но на практике вы наверняка пожелаете реализовать нечто более сложное, чем этот сценарий:
import cherrypy
import os
# программный код, выполняющий запросы XHR, будет находиться в файле foo.html,
# и это видно в следующей директиве config
current_dir = os.getcwd()
config = {'/foo.html' :
{
'tools.staticfile.on' : True,
'tools.staticfile.filename' : os.path.join(current_dir, 'foo.html')
}
}
class Content:
@cherrypy.expose
def index(self):
#############################################################
# для большей простоты этот пример не использует библиотеку json.
# для реализации более сложных сценариев, чем этот, вы можете
# получить замечательную библиотеку по адресу http://json.org
############################################################
# прочитать необработанные данные, переданные методом POST
rawPost = cherrypy.request.body.read()
# преобразовать в объект
obj = eval(rawPost) #ВНИМАНИЕ! Это дыра в системе безопасности!
#вы предупреждены...
# обработать данные
if obj["method"] == "sum":
result = sum(obj["params"][0])
if obj["method"] == "sumOfSquares":
result = sum([i*i for i in obj["params"][0]])
# вернуть ответ в формате json
return str({"result" : result})
# запустить веб-сервер, который будет прослушивать порт 8080
cherrypy.quickstart(Content(), '/', config=config)
Функция JsonpService используется практически так же, как и Json-Service. В дистрибутиве Dojo имеется пример файла SMD (dojox/rpc/yahoo.smd) для доступа к службе Yahoo!, который при желании можно опробовать.