tornado websocket+redis订阅推送的实现

原文地址:「静月疏影」:https://blog.csdn.net/qq_769932247/article/details/87883812

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()

 



 

 

 

posted @ 2019-08-23 23:25  逐梦客!  阅读(1113)  评论(0)    收藏  举报