这已经花费了我很多小时的谷歌搜索,但我仍然无法让它工作,是时候向 SO 寻求帮助了 :-)
我尝试组装一个简单的测试应用程序,其中前端用 Pyjamas 编写,后端运行在Web.py上。他们应该通过 JSON-RPC 相互交谈。所需的功能是让用户输入一个字符串,然后将其转换为大写。
睡衣在线书籍《世界的其他地方》中有关于如何使用 JSON-RPC 的描述,其中将各种技术混合在一起,因此难以解析。通过查看来自Amund Tveit 的博客等的提示,我拼凑了以下内容:
1)非常简单的服务器脚本:
import web
import json
import os
urls = (
'/json', 'JSONHandler',
'/json/', 'JSONHandler',
)
app = web.application(urls, globals())
class JSONHandler:
def json_upper(self,args):
return [args[0].upper()]
def json_markdown(self,args):
return [args[0].lower()]
def POST(self):
args = json.loads(web.data())
print args
json_func = getattr(self, 'json_%s' % args[u"method"])
json_params = args[u"params"]
json_method_id = args[u"id"]
result = json_func(json_params)
# reuse args to send result back
args.pop(u"method")
args["result"] = result[0]
args["error"] = None # IMPORTANT!!
web.header("Content-Type","text/html; charset=utf-8")
return json.dumps(args)
if __name__ == "__main__":
app.run()
它确实有效,使用依赖于Josh Marshall 的 JSON-RPC 库的简单查询脚本(未显示)进行测试。
2)睡衣的客户端脚本也很简单:
# Client example from Amund Tveit's blog
# http://amundblog.blogspot.co.at/2008/12/ajax-with-python-combining-pyjs-and.html
# note: ui and JSONService were not prefixed with pyjamas, but that's needed
from pyjamas.ui import RootPanel, TextArea, Label, Button, HTML, VerticalPanel, HorizontalPanel, ListBox
from pyjamas.JSONService import JSONProxy
class Client:
def onModuleLoad(self):
self.TEXT_WAITING = "Waiting for response..."
self.TEXT_ERROR = "Server Error"
# This is the remote service
self.remote_server = UpperService()
self.status=Label()
self.text_area = TextArea()
self.text_area.setText(r"Please uppercase this string")
self.text_area.setCharacterWidth(80)
self.text_area.setVisibleLines(8)
self.button_py = Button("Send to Python Service", self)
buttons = HorizontalPanel()
buttons.add(self.button_py)
buttons.setSpacing(8)
info = r'Upper-case a string using JSON-RPC'
panel = VerticalPanel()
panel.add(HTML(info))
panel.add(self.text_area)
panel.add(buttons)
panel.add(self.status)
RootPanel().add(panel)
def onClick(self, sender):
self.status.setText(self.TEXT_WAITING)
text = self.text_area.getText()
# (data, response_class): if the latter is 'self', then
# the response is handled by the self.onRemoteResponse() method
if self.remote_server.upper(self.text_area.getText(), self) < 0:
self.status.setText(self.TEXT_ERROR)
def onRemoteResponse(self, response, request_info):
self.status.setText(response)
def onRemoteError(self, code, message, request_info):
self.status.setText("Server Error or Invalid Response: ERROR " + code + " - " + message)
# AJAX calls must come from the same server, only the path is given here
class UpperService(JSONProxy):
def __init__(self):
JSONProxy.__init__(self, "/json/", ["upper"])
我用 PyJs 编译它,将默认output
目录重命名为static
web.py 可以为它服务,编辑static/Client.html
以便内部引用指向static
:
<html>
<!-- auto-generated html - You should consider editing and adapting this
to suit your requirements. No doctype used here to force quirks mode; see
wiki for details: http://pyjs.org/wiki/csshellandhowtodealwithit/
-->
<head>
<title>Client (Pyjamas Auto-Generated HTML file)</title>
<meta name="pygwt:module" content="/static/Client"> <!-- was content="Client" -->
</head>
<body style="background-color:white">
<script type="text/javascript" src="/static/bootstrap.js"></script> <!-- was src="bootstrap.js" -->
<iframe id="__pygwt_historyFrame" style="display:none;"></iframe>
</body>
</html>
...然后将浏览器指向http://localhost:8080/static/Client.html
. 我得到的只是一个空白页面,检查static/Client.html
上面显示的页面源,因此它确实提供给了浏览器。服务器的日志还显示至少有一些页面已被提供:
http://0.0.0.0:8080/
127.0.0.1:61466 - - [14/Mar/2013 13:59:39] "HTTP/1.1 GET /static/Client.html" - 200
127.0.0.1:61466 - - [14/Mar/2013 13:59:40] "HTTP/1.1 GET /static/Client.nocache.html" - 200
127.0.0.1:61466 - - [14/Mar/2013 13:59:40] "HTTP/1.1 GET /static/Client.safari.cache.html" - 200
然而,没有迹象表明出了什么问题。尝试了各种其他 URL 组合,重命名目录,使用 -d 选项编译睡衣部分,希望获得调试堆栈跟踪......无济于事。
有没有人成功让睡衣和 Web.py 一起工作?如果是,那么请分享如何。谢谢。
PS:我正在使用 web.py V0.37 和最新的睡衣开发版本。(当前的稳定版本 V0.8.1 也不起作用。)