首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

GAE1.4尝新

2012-10-26 
GAE1.4尝鲜GAE1.4发布了,带来了很多新的功能。不过我最在意的有两个:一是支持代码下载;二是支持及时通讯(ch

GAE1.4尝鲜
GAE1.4发布了,带来了很多新的功能。不过我最在意的有两个:一是支持代码下载;二是支持及时通讯(channel api),现在我们来玩玩这两个东西。

1、代码下载

我们一般通过appcfg.py来上传、更新代码,但是没有下载的功能。如果换了一台机器,又看到不代码,真的很窝火。不过,现在GAE提供了,真的很方便,赞一个GAE。下载代码很简单,看一个简单的例子:

Usage: appcfg.py [options] download_app -A app_id [ -V version ] <out-dir>

C:\Users\Administrator\Desktop>appcfg.py download_app -A flyingzl -V 2 flyingzl-projectD:\program\python\GAE\appcfg.py:42: DeprecationWarning: the sha module is deprecated; use the hashlib module instead  os.path.join(DIR_PATH, 'lib', 'django'),D:\program\python\GAE\google\appengine\tools\dev_appserver_login.py:33: DeprecationWarning: the md5 module is deprecated; use hashlib instead  import md5Server: appengine.google.com.Fetching file list...Fetching files...[1/23] chat.py[2/23] send_mail.py[3/23] hello_template.html[4/23] hello_user.py...


2、即时通讯支持(channel API)

即时通信,即我们常说的comet,用于模拟和远程服务端长连接,常见的技术有轮询(poll)、推送(push)、websocket(html5支持,不过现在大部分服务器还不支持,GAE以后也会支持这个!)。关于后台的实现,各种各样,开源的技术也不少,我们看看google的实现


从图可以看出,在我们和GAE进行通信时,中间其实还有一个基于XMLPP的google talk,我们每次通信首先走的是google talk然后google talk再和gae进行通信。。。在之后的列子中,通过firebug的console我们可以看到加载google talk脚本的过程。

接着看图:



可以看到,在browser端,我们是和在一个看不到的iframe在通信,我们把数据传给这个隐藏的iframe,然后iframe再和google talk通信,然后再和GAE通信,貌似有点小复杂。不过没有关系,这些都是对用户透明的。说了这么多废话,直接看api,哈哈



如果大家熟悉html5的websocket,可以看到channel api的实现完全和websocket一致。



很简单吧,现在我们做一个样例,就是做一个非常简单的聊天室。有兴趣的童鞋可以好好改造下,界面如下:



3、代码实现聊天室

首先创建服务端
#coding=utf-8'''Created on 2010-12-4@author: flyingzl'''from google.appengine.ext import webappfrom google.appengine.ext.webapp import util,templatefrom google.appengine.api import channelfrom hashlib import md5import timeclass Chat(webapp.RequestHandler):        def get(self):        self.response.headers['Content-Type']='text/html;charset=utf-8'        key=md5('1234567890').hexdigest()        client_id=channel.create_channel(key)        self.response.out.write(template.render("templates/chat.html", {'channel_id':client_id}))                class ChatSender(webapp.RequestHandler):    def get(self):        self.response.headers['Content-Type']='text/html;charset=utf-8'        self.error(500)        self.response.out.write('只支持Post请求')        def post(self):        key=md5('1234567890').hexdigest()        message=self.request.get('message','')        now=time.strftime("%Y-%m-%d %H:%M:%S")        ip=self.request.environ['REMOTE_ADDR']        try:            channel.send_message(key, "%s(%s)-->%s"%(ip,now,message))        except channel.InvalidChannelClientIdError:            self.error(500)            self.response.out.write("Channel标识符不合法")        except channel.InvalidMessageError:            self.error(500)            self.response.out.write("发送的消息太长,最大长度不能超过")+channel.MAXIMUM_MESSAGE_LENGTH+"个字节"                            def main():    app=webapp.WSGIApplication([('/chat',Chat),('/chat/sender',ChatSender)],debug=True);    util.run_wsgi_app(app)if __name__=='__main__':    main()


代码比较简单,主要有两个过程,一个是创建channel,另外一个是通过channel发送消息。

再看看客户端:

<!doctype><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta><title>Chat</title><style type="text/css">#mainDiv{width:600px;height:400px;padding:5px;margin:10px auto;border:1px solid lightblue;}#message{width:100%;height:370px;margin-bottom:5px;}#userMessage{width:450px;margin-right:2px;}</style></head><body><div id="mainDiv"><textarea id='message'></textarea><input id="userMessage"  /><button id='btn' disabled onClick="sendMessage()">正在连接服务器……</button></div><script type="text/javascript" src="/_ah/channel/jsapi"></script><script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script><script>var channel_id='{{channel_id}}',timeoutID='';$(function(){var channel=new goog.appengine.Channel(channel_id),socket=channel.open();socket.onopen=function(){$('#btn').html("发送").removeAttr('disabled');}socket.onmessage=function(data){var message=$("#message").val();$.trim(message)?$("#message").val(message+"\n"+data.data):$("#message").val(data.data);}});function sendMessage(message){if(timeoutID){alert("您发送的太快了,休息一下下……");return;}var message=$('#userMessage').val();if(!$.trim(message)){alert("请输入要发送的消息!");$('#userMessage').focus();return;}$.ajax({type:'POST',data:"message="+message,url:'/chat/sender',error:function(err){alert(err.responseText);}});$('#userMessage').val('')timeoutID=setTimeout(function(){timeoutID='';},500);}</script></body></html>


创建channel的过程是不是和websocket很像?我们只需要监听onopen、onmessage就可以获得服务器传来的消息;不过我有点没搞明白,为什么不可以像websocket那样通过socket.send方法发送数到远程呢?或许本身gae就支持的不好。

到此,一个简单的聊天室就做好了,几行代码,就完成了一个我们之前要花费很大气力才能做完的,GAE真的是太赞了,继续关注!

代码本身很简单,我就不上传代码了。大家看明白就可以咯!祝大家周末愉快~~ 1 楼 sumaolin 2010-12-08   呵呵……
那以后在浏览器端就可以直接聊天了,不用QQ什么的客户端啦!
开源才是走向统一 2 楼 dengzhangtao 2010-12-09   那java怎么弄? 3 楼 fm_974 2010-12-09   一定要裝Google Talk客戶端? 4 楼 qiaoqinqie 2010-12-09   GAE 被封锁了? 5 楼 maltose 2010-12-10   已经被封了

热点排行