大家好,下面我和大家分享一下非诚勿扰tornado的实现方式。
非诚勿扰APK地址: http://as.baidu.com/a/item?docid=475931&f=web_alad_1
概念介绍:
Comet:基于HTTP长连接的“服务器推”技术
基于Comet的技术主要分为流(streaming)方式和长轮询(long-polling)方式。
首先看Comet这个单词,很多地方都会说到,它是“彗星”的意思,顾名思义,彗星有个长长的尾巴,以此来说明客户端发起的请求是长连的。即用户发起请求后就挂起,等待服务器返回数据,在此期间不会断开连接。流方式和长轮询方式的区别就是:对于流方式,客户端发起连接就不会断开连接,而是由服务器端进行控制。当服务器端有更新时,刷新数据,客户端进行更新;而对于长轮询,当服务器端有更新返回,客户端先断开连接,进行处理,然后重新发起连接。
长轮询(long-polling)方式
流(streaming)方式
根据上面两种方式,我使用了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 functools
import hashlib
import logging
import struct
import time
import tornado.escape
import tornado.web
from tornado import httpserver
import tornado.websocket
import random
class 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.asynchronous
def post(self):
self.get_data(callback=self.on_finish)
def get_data(self, callback):
if self.request.connection.stream.closed():
return
num = 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.asynchronous
def post(self):
self.get_data(callback=self.on_finish)
def get_data(self, callback):
if self.request.connection.stream.closed():
return
num = 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 = 8888
print "[start server on port:%s]......." % port
http_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/。
附件中有例子,有想完的朋友,拿去玩吧
分享到:
相关推荐
把酒言欢话聊天,基于Vue3.0+Tornado6.1+Redis发布订阅(pubsub)模式打造实时(websocket)通信聊天系统,非阻塞(aioredis)
在全民编程的大环境下,学习编程的人与日俱增,而为开发者提供问答的社区也逐渐流行起来。例如,国外最著名技术问答社区 ...本章主要使用 Python中的轻量级异步框架 Tornado来实现一个类似 Stackoverflow的问答社区网站。
Python高效开发实战+Django+Tornado+Flask+Twisted源代码 Python高效开发实战+Django+Tornado+Flask+Twisted源代码 Python高效开发实战+Django+Tornado+Flask+Twisted源代码
资源分类:Python库 所属语言:Python 资源全名:tornado-redis-session-0.1.3.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
龙卷风-redis 简单的异步 Tornado-redis 连接器 去做: 处理与 ioloop.WRITE 的连接 处理第二次和更多读取操作
认识Tornado+II和Vxworks
Python+tornado+mysql 测试学习项目
Python高效开发实战Django+Tornado+Flask+Twisted完整源代码,包括macos
vue后台代码,搭配后端Tornado,以及Nginx服务器,以及Mysql。
最近在centos部署了一套python框架,总结如下。在32位机器上离线方式部署VMware10+Centos6.9+Openssh7.5+MySQL5.1+Python2.7+Tornado+SQLAlchemy,有问题请联系407169441@qq.com
Tornado+vxWorks的文档
vue前台代码,搭配后端Tornado,以及Nginx服务器,以及Mysql。
在之前的一篇文章中提到了用Django+Celery+Redis实现了异步任务队列,只不过消息中间件使用了redis,redis作为消息中间件可谓是差强人意,功能和性能上都不如Rabbitmq,所以本次使用tornado框架结合celery,同时消息...
龙卷风重演基于Redis的服务器端会话中间件安装pip install tornado-redis-session用法 from tornado . httpserver import HTTPServerfrom tornado . ioloop import IOLoopfrom tornado . web import authenticated ,...
实现登录验证、注册、加好友、加群、私聊、群聊+1.0版本。 MySQL 是一款广受欢迎的开源关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现隶属于美国甲骨文公司(Oracle)。自1998年首次发布以来,MySQL以...
概念证明测试 PyReact + Tornado + Motor + Jinja2 + reactjs $ mkdir tornado_react && cd tornado_react $ virtualenv --no-site-packages -p python3.4 . $ source bin/activate $ git clone ...
异步:tornado+motor全异步库,增加web高并发访问效率 redis:抛弃php中以文件形式保存session的做法,以redis内存数据库保存session,增加速度。 安全: CSP:全站默认开启CSP,以新一代的前端安全策略防御前端安全...
今天小编就为大家分享一篇tornado+celery的简单使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧