使用来自Pajamas / PyJs的JSON-RPC调用和web.py后端

时间:2013-03-14 13:36:38

标签: web.py pyjamas

这已经花了我很多小时的谷歌搜索,我仍然无法让它工作,有时间去寻求帮助: - )

我尝试组合一个简单的测试应用程序,其中前端是用睡衣编写的,后端运行在Web.py上。他们应该通过JSON-RPC互相交谈。所需的功能是让用户输入一个字符串,然后将其转换为大写字母。

在睡衣在线书籍"Rest of the World"中有关于如何使用JSON-RPC的描述,它将各种技术混合在一起,因此难以解析。通过查看提示,例如来自Amund Tveit's blog等。我拼凑了以下内容:

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's JSON-RPC library的简单查询脚本(未显示)进行测试。

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选项编译Pajamas部分,希望获得调试堆栈跟踪......无济于事。

有没有人成功让Pajamas和Web.py一起工作?如果是,那么请分享如何。感谢。

PS:我正在使用web.py V0.37和最新的Pajamas开发版本。 (目前的稳定版本V0.8.1也不起作用。)

1 个答案:

答案 0 :(得分:1)

我知道你可能已经解决了这个问题,但找到你的代码帮助我修复了我的问题,用webpy找到pyjs的在线工作示例似乎很棘手。

您的问题出在客户端脚本端,您需要添加一些代码来启动客户端:

if __name__ == '__main__':
    app = Client()
    app.onModuleLoad()

此外,为了避免出现的错误,您的第一行导入应更改为:

from pyjamas.ui.RootPanel import RootPanel
from pyjamas.ui.TextArea import TextArea
from pyjamas.ui.Label import Label
from pyjamas.ui.Button import Button
from pyjamas.ui.HTML import HTML
from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.HorizontalPanel import HorizontalPanel
from pyjamas.ui.ListBox import ListBox