python tornado简易ws聊天室测试
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
from datetime import datetime
import tornado
from tornado.options import define, options
from tornado.websocket import WebSocketHandler
import signal
import sys
# 设置服务器端口
define("port", default=6228, type=int)
class ChatHandler(WebSocketHandler):
users = set() # 用来存放在线用户的容器
def open(self, *args, **kwargs):
id_param = self.get_argument("id", default=None)
print(id_param)
# 建立连接后添加用户到容器中
self.users.add(self)
# 向已在线用户发送消息
for user in self.users:
remote_ip, port = self.request.connection.context.address
now = datetime.now().strftime("%H:%M:%S")
user.write_message("[{}][{}:{}]-进入聊天室".format(now, remote_ip, port))
# 安排定时发送 ping 消息,毫秒,或者把这个方法提出来,弄成全局的定时器,服务于全部在线人群
self.heartbeat_callback = tornado.ioloop.PeriodicCallback(
self.send_heartbeat, 10000
)
self.heartbeat_callback.start()
def on_message(self, message):
# 向在线用户广播消息
now = datetime.now().strftime("%H:%M:%S")
remote_ip, port = self.request.connection.context.address
for user in self.users:
user.write_message("[{}][{}:{}] {}".format(now, remote_ip, port, message))
def on_close(self):
# 用户关闭连接后从容器中移除用户
now = datetime.now().strftime("%H:%M:%S")
remote_ip, port = self.request.connection.context.address
self.users.remove(self)
self.heartbeat_callback.stop()
for user in self.users:
user.write_message("[{}][{}:{}]-离开聊天室".format(now, remote_ip, port))
def check_origin(self, origin):
return True # 允许WebSocket的跨域请求
# 发送心跳的方法
def send_heartbeat(self):
try:
# 发送 ping 消息
self.write_message("ping", binary=False)
except Exception as e:
# 如果发送失败,可能是连接已经关闭
self.users.remove(self)
self.heartbeat_callback.stop()
for user in self.users:
user.write_message("离开聊天室")
def router():
return tornado.web.Application([
(r"/ws", ChatHandler),
],
debug=True
)
def main():
app = router()
# 设置信号处理器,优雅地处理 SIGINT 信号
def signal_handler(sig, frame):
print('Stopping Tornado web server...')
tornado.ioloop.IOLoop.current().stop()
sys.exit(0)
tornado.options.parse_command_line()
signal.signal(signal.SIGINT, signal_handler)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
if __name__ == "__main__":
main()
分类:
python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了