当前位置: 代码迷 >> 综合 >> tornado websocket+redis订阅推送的实现
  详细解决方案

tornado websocket+redis订阅推送的实现

热度:17   发布时间:2023-12-06 19:21:07.0

整整踏了一周的坑,终于算是填上了,说到底还是tornado的框架不太成熟,而且各版本还存在很大的差异,先说我的环境

python==3.7

tornado==4.1

用到tornado-redis,非常好用的一个包

from __future__ import print_functionimport jsonimport tornado.httpserver
import tornado.web
import tornado.websocket
import tornado.ioloop
import tornado.genimport tornadoredis
from tornado import genc = tornadoredis.Client(selected_db=1)
c.connect()#可以注释不用
class MainHandler(tornado.web.RequestHandler):def get(self):self.render("template.html", title="PubSub + WebSocket Demo")#也可以注释不用
class NewMessageHandler(tornado.web.RequestHandler):def post(self):message = self.get_argument('message')c.publish('test_channel', message)self.set_header('Content-Type', 'text/plain')self.write('sent: %s' % (message,))#这个主要
class MessageHandler(tornado.websocket.WebSocketHandler):#存储用户信息userDict = dict()userlist = set()def __init__(self, *args, **kwargs):super(MessageHandler, self).__init__(*args, **kwargs)self.userlist.add(self)@tornado.gen.enginedef listen(self,callback,user,data):if user not in self.userDict.keys():self.client = tornadoredis.Client()self.client.connect()self.userDict[user]={'cl':self.client,'con':callback}#第一次协程订阅yield tornado.gen.Task(self.userDict[user]['cl'].subscribe, data)#监听,回调self.client.listen(self.sendMessage)else:self.userDict[user]['con'] = callbackself.userDict[user]['cl'].subscribe(data)def on_message(self, message):tt = json.loads(message)# tt = {"msg":"sub","user":"a","data":"rb1910"}if tt['msg'] == 'sub':self.listen(self,tt['user'],tt['data'])elif tt['msg'] == 'unsub':self.UnSub(self,tt['user'],tt['data'])pass@gen.coroutinedef sendMessage(self, msg):if msg.kind == 'message':for k,v in self.userDict.items():if self == v['con']:print(k)self.write_message(str(msg.body))if msg.kind == 'disconnect':# Do not try to reconnect, just send a message back# to the client and close the client connectionself.write_message('The connection terminated ''due to a Redis server error.')# self.close()def on_close(self):if self.client.subscribed:self.client.unsubscribe('test_channel')self.client.disconnect()def check_origin(self, origin):return Truedef UnSub(self,callback,user,data):if user not in self.userDict.keys():print('error')else:self.userDict[user]['con'] = callbackself.userDict[user]['cl'].unsubscribe(data)application = tornado.web.Application([(r'/', MainHandler),(r'/msg', NewMessageHandler),(r'/track', MessageHandler),
])if __name__ == '__main__':http_server = tornado.httpserver.HTTPServer(application)http_server.listen(8888)tornado.ioloop.IOLoop.instance().start()