tornado websocket +redis 如何实现广播功能,为什么我这只能一个客户端连接之后就会阻塞,怎么样存用户的连接,如何不停的给用户推送信息

2019-02-13 14:14:34 +08:00
 769932247
# 引入需要的模块
import os

from tornado.web import RequestHandler, Application,Cookie
from tornado.httpserver import HTTPServer
from tornado.websocket import WebSocketHandler
from tornado.ioloop import IOLoop

from redisp import redisPool
from tornado.httpclient import AsyncHTTPClient #异步的 http 请求客户端

#
# from queue import Queue
# q = Queue()

class BaseHandler(RequestHandler):
pass

# 定义首页视图处理类,提示用户登录
class IndexHandler(BaseHandler):
def get(self):
self.render('index.html')


# 定义登录视图处理类
class LoginHandler(BaseHandler):
def get(self):
# 获取用户登录的昵称
nickname=self.get_argument('nickname')
# 将用户登录的昵称保存在 cookie 中,安全 cookie
self.set_secure_cookie('nickname',nickname,expires_days=None)
self.render('chat.html',nickname=nickname)


# 定义接收 /发送聊天消息的视图处理类,继承自 websocket 的 WebSocketHandler
class ChatHandler(WebSocketHandler):
# 定义一个集合,用来保存在线的所有用户
online_users = set()
uselist = []
# 从客户端获取 cookie 信息
redisPool = redisPool()
rp = redisPool.getRedisPool()

@classmethod
def send_trick(cls,rp,user):
old_send_message = ''
while True:
send_message = rp.get('SSEMarketData')
if old_send_message != send_message:
# for user in self.online_users:
user.write_message(send_message)
old_send_message = send_message

# 重写 open 方法,当有新的聊天用户进入的时候自动触发该函数
def open(self):
# 当有新的用户上线,将该用户加入集合中
self.online_users.add(self)
self.uselist.append(self)
# 将新用户加入的信息发送给所有的在线用户
for user in self.online_users:
user_name = self.get_secure_cookie("nickname").decode('utf-8')
user.write_message(' [%s ] 进入了聊天室' % user_name)


# 重写 on_message 方法,当聊天消息有更新时自动触发的函数
def on_message(self, message):
# 将在线用户发送的消息通过服务器转发给所有的在线用户

for user in self.online_users:
user_name = self.get_secure_cookie("nickname").decode('utf-8')
user.write_message('%s:%s' % (user_name, message))
if message:
old_send_message = ''
while True:
send_message = self.rp.get('SSEMarketData')
if old_send_message != send_message:
# for user in self.online_users:
self.write_message(send_message)
old_send_message = send_message
# ChatHandler.send_trick(self.rp,self.uselist[-1])


# 重写 on_close 方法,当有用户离开时自动触发的函数
def on_close(self):
# 先将用户从列表中移除
self.online_users.remove(self)
# 将该用户离开的消息发送给所有在线的用户
for user in self.online_users:
user.write_message(' [%s ] 离开了聊天室~' % self.request.remote_ip)


def check_origin(self, origin):
return True


# 程序运行入口
if __name__=='__main__':

BASE_DIR = os.path.dirname(__file__)
app = Application([
(r'/', IndexHandler),
(r'/login', LoginHandler),
(r'/chat', ChatHandler),
],
template_path=os.path.join(BASE_DIR, 'templates'),
static_path=os.path.join(BASE_DIR, 'static'),
debug=True,
login_url='/login',
cookie_secret='CPFL2FJOTQGzR/8DXZEyfAjxS9hSTk0Bs0f/A12RMnwI8UvYUk5NAbNH/wNdkTJ8')
server = HTTPServer(app)
server.listen(8000)
IOLoop.current().start()
1074 次点击
所在节点    Python
1 条回复
yangbuwei
2019-02-14 12:02:14 +08:00
tornado 有自带的 websocket,,可以实现你现在的功能,,网上好像有现成的代码,,你搜一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/534537

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX