Young87

当前位置:首页 >个人收藏

tornado websocket+redis订阅推送的实现

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

python==3.7

tornado==4.1

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

from __future__ import print_function

import json

import tornado.httpserver
import tornado.web
import tornado.websocket
import tornado.ioloop
import tornado.gen

import tornadoredis
from tornado import gen

c = 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.engine
    def 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'] = callback
            self.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.coroutine
    def 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 connection
            self.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 True

    def UnSub(self,callback,user,data):

        if user not in self.userDict.keys():
           print('error')
        else:
            self.userDict[user]['con'] = callback
            self.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()

 

 

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: Linux之重定向,管道符,通配符,转义字符

下一篇: Android程序员接私活完整攻略

精华推荐