ProtoRPC 的 Hello World
这个小节演示一下从远端接受一个消息(包含了用户名 HelloRequest.my_name),并返回一个响应(HelloResponse.hello)。
from google.appengine.ext import webappfrom google.appengine.ext.webapp import utilfrom protorpc import messagesfrom protorpc.webapp import service_handlersfrom protorpc import remotepackage = 'hello'# Create the request string containing the user's nameclass HelloRequest(messages.Message):my_name = messages.StringField(1, required=True)# Create the response stringclass HelloResponse(messages.Message):hello = messages.StringField(1, required=True)# Create the RPC service to exchange messagesclass HelloService(remote.Service):@remote.remote(HelloRequest, HelloResponse)def hello(self, request):return HelloResponse(hello='Hello there, %s!' %request.my_name)# Map the RPC service and path (/hello)service_mappings = service_handlers.service_mapping([('/hello', HelloService),])# Apply the service mappings to Webappapplication = webapp.WSGIApplication(service_mappings)def main():util.run_wsgi_app(application)if __name__ == '__main__':main() 开始 ProtoRPC 之旅
在这里我们使用 App Engine Getting Started Guide (Python) 的留言板示例(http://code.google.com/appengine/docs/python/gettingstarted/)。用户可以在线访问这个留言板(已经包含在 Python SDK 中),编写留言,查看所有用户的留言。
接下来将把 ProtoRPC 应用到这个基本的留言板中,使得 Web 应用能够存取其数据。但这个教程只涵盖了使用 ProtoRPC 来扩展留言板功能,其实你可以做到更多,比如编写一个工具读取用户提交的所有消息或创建一个每天有多少条留言的图表。根据特定的应用,可以随意使用 ProtoRPC,重要的是 ProtoRPC 可以让你随便折腾你的数据。
万事之始,是创建一个名为 postservice.py 的文件,所有存取留言板应用数据的远程方法都在其中实现。 创建 PostService 模块
第一步,在应用程序目录下创建一个名为 postservice.py 的文件,它将实现两个方法:一个用以远程提交数据,另一个用以远程获取数据。 燃烧吧,消息!
消息是 ProtoRPC 的基本数据类型,通过声明一个 Message 继承下来的子类来定义消息,然后定义与消息字段相应的类属性。
留言板服务能够让用户提交一个留言,那么就定义一个消息来表示一个留言吧:
from protorpc import messagesclass Note(messages.Message):text = messages.StringField(1, required=True)when = messages.IntegerField(2)
Note 消息定义了两个字段,text 和 when。每一个字段都有自己的类型,比如 text 字段的类型提 unicode 字符串,用以表示用户通过留言板页面提交的内容,而 when 字段就是一个整数,用以表示用户提交的时间戳。除此之外:
每个字段有一个唯一的数值(如 text 是 1,when 是 2),这是底层网络协议要用到的字段标识
定义 text 为必填字段。每个字段默认是可选的,所以要用 required=True 来定制为必填字段。
可以通过 Note 类的构建函数来给字段赋值:
# Import the standard time Python library to handle the timestamp.import timenote_instance = Note(text=u'Hello guestbook!', when=int(time.time())
也可以操作普通的 Python 属性一样读、写字段,比如下面的代码可以改变消息:
print note_instance.textnote_instance.text = u'Good-bye guestbook!'print note_instance.text# Which outputs the following>>>Hello guestbook!Good-bye guestbook! 定义服务
一个服务就是指一个从 Service 基类继承的类,服务的远程方法由 remote 装饰器标识。服务的每个方法都接受单个消息作为参数,并返回一个消息作为响应。
现在来定义 PostService 的第一个方法。如果你还没有准备好,记得先在你应用目录下创建 postservice.py 文件,或如果你觉得有必要的话就读一下留言板教程(http://code.google.com/appengine/docs/python/gettingstarted/)。PostService 与留言板教程一样,使用 guestbook.Greeting 来存储提交的数据。
import datetimefrom protorpc import message_typesfrom protorpc import remoteimport guestbookclass PostService(remote.Service):# Add the remote decorator to indicate the service methods@remote.remote(Note, message_types.VoidMessage)def post_note(self, request):# If the Note instance has a timestamp, use that timestampif request.when is not None:when = datetime.datetime.utcfromtimestamp(request.when)# Else use the current timeelse:when = datetime.datetime.now()note = guestbook.Greeting(content=request.text, date=when)note.put()return message_types.VoidMessage()
remote 装饰器有两个参数: