0

这已经花费了我很多小时的谷歌搜索,但我仍然无法让它工作,是时候向 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目录重命名为staticweb.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 也不起作用。)

4

1 回答 1

1

I know you're probably over this, but finding your code helped me fixing mine and it seems tricky to find working examples online for pyjs with webpy.

Your problem was on the client script side, where you needed to add some code to start the client:

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

Moreover, to avoid errors that will then appear, your first line of import should be changed to:

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
于 2013-06-18T22:37:24.860 回答