读书人

非诚勿扰聊天兑现tornado + redis

发布时间: 2012-09-28 00:03:35 作者: rapoo

非诚勿扰聊天实现,tornado + redis

?

大家好,下面我和大家分享一下非诚勿扰tornado的实现方式。

非诚勿扰APK地址:?http://as.baidu.com/a/item?docid=475931&f=web_alad_1

?

概念介绍:

Comet:基于HTTP长连接的“服务器推”技术

基于Comet的技术主要分为流(streaming)方式和长轮询(long-polling)方式。

首先看Comet这个单词,很多地方都会说到,它是“彗星”的意思,顾名思义,彗星有个长长的尾巴,以此来说明客户端发起的请求是长连的。即用户发起请求后就挂起,等待服务器返回数据,在此期间不会断开连接。流方式和长轮询方式的区别就是:对于流方式,客户端发起连接就不会断开连接,而是由服务器端进行控制。当服务器端有更新时,刷新数据,客户端进行更新;而对于长轮询,当服务器端有更新返回,客户端先断开连接,进行处理,然后重新发起连接。

长轮询(long-polling)方式

非诚勿扰聊天兑现,tornado + redis

流(streaming)方式

非诚勿扰聊天兑现,tornado + redis

根据上面两种方式,我使用了Streaming的方式,原因很简单,在移动互联网的网络环境不如互联网的网络环境,建立tcp链接的开销比较大,所以我们使用streaming方式,在客户端意外断开链接后进行重链接。

具体的实现,其实实现起来

class Chat(object):    """Chat Redis Server"""    def __init__(self):        redis_settings = settings.redis_settings        config = redis_settings["REDIS_CHAT"]        self.redis = Redis(config["servers"], config["port"], config["db"])    def chat_list_key(self, from_user, to_user):        return "chat_messages:%s:%s" % (from_user.id, to_user.id)        def say(self, from_user, to_user, msg, img,sys='', urla="",urlb=""):        """chat to some one"""        #add unread list        pipeline = self.redis.pipeline()        try:            #add msg to unread list            chat_list_name = self.chat_list_key(from_user, to_user)            pipeline.rpush(chat_list_name, msg)            pipeline.execute()        except:            pipeline.reset()    def read(self, from_user, to_user, count=20, set_read=True):        key = self.chat_list_key(from_user, to_user)        data = self.redis.lrange(key, 0, count) or []        if set_read:            pipeline = self.redis.pipeline()            try:                pipeline.delete(key)                pipeline.execute()            finally:                pipeline.reset()                        return data

?很简单,简单就是美吗:

?

?

cimport functoolsimport hashlibimport loggingimport structimport timeimport tornado.escapeimport tornado.webfrom tornado import httpserverimport tornado.websocketimport randomclass PollingHandler(tornado.web.RequestHandler):def post(self):num = random.randint(1, 100)self.write("welcome:E" + str(num))self.finish()class StreamingHandler(tornado.web.RequestHandler):@tornado.web.asynchronousdef post(self):self.get_data(callback=self.on_finish)def get_data(self, callback):if self.request.connection.stream.closed():returnnum = random.randint(1, 100)callback(num)def on_finish(self, data):self.write("Server says: %d" % data)self.flush()tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 3,lambda: self.get_data(callback=self.on_finish))class LongPollingHandler(tornado.web.RequestHandler):@tornado.web.asynchronousdef post(self):self.get_data(callback=self.on_finish)def get_data(self, callback):if self.request.connection.stream.closed():returnnum = random.randint(1, 100)tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 3,lambda: callback(num))def on_finish(self, data):self.write("Server says: %d" % data)self.finish()class WebSocketHandler(tornado.websocket.WebSocketHandler):def open(self):num = random.randint(1, 100)self.write_message("Server Say:"+str(num))def on_message(self, message):logging.info("getting message %s", message)self.write_message("You say:" + message)def on_close(self):print "[WebSocket closed]......"if __name__ == "__main__":application = tornado.web.Application([(r"/websocket", WebSocketHandler),(r"/polling", PollingHandler),(r"/streaming", StreamingHandler),(r"/longpolling", LongPollingHandler),(r"/static/(.*)", tornado.web.StaticFileHandler, {"path": "/Users/liuzheng/py.work.dir/comet"}),                                         ])port = 8888print "[start server on port:%s]......." % porthttp_server = httpserver.HTTPServer(application)http_server.bind(port)http_server.start(2)tornado.ioloop.IOLoop.instance().start()

?

?

WebSocket:未来方向

以上不管是Comet的何种方式,其实都只是单向通信,直到WebSocket的出现,才是B/S之间真正的全双工通信。不过目前WebSocket协议仍在开发中,目前Chrome和Safri浏览器默认支持WebSocket,而FF4和Opera出于安全考虑,默认关闭了WebSocket,IE则不支持(包括9),目前WebSocket协议最新的为“76号草案”。有兴趣可以关注http://dev.w3.org/html5/websockets/。

附件中有例子,有想完的朋友,拿去玩吧

读书人网 >移动开发

热点推荐