Tornado搭建WebSocket持续推送信息(二)

2 篇文章 0 订阅
2 篇文章 0 订阅

前言

  • tornado version 6.2
  • 逻辑:
    • 用户建立连接后创建单独的定时任务
    • 在定时任务中进行消息推送服务(异步)

代码

# -*- coding:utf-8 -*-
# @Author: Aiden
# @Date: 2022/9/5 13:09

import asyncio
import datetime

from loguru import logger as log
from concurrent.futures import ThreadPoolExecutor

from tornado.web import Application
from tornado.ioloop import PeriodicCallback
from tornado.websocket import WebSocketHandler


class MyThreadPool:
    executor = ThreadPoolExecutor(max_workers=5)


class MyWsHandler(WebSocketHandler, MyThreadPool):

    def data_received(self, chunk: bytes):
        pass

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.event_loop = None

    def check_origin(self, origin):
        """允许跨域请求"""
        return True

    def on_ping(self, data):
        print("ping", data)
        # self.ping(str(round(time.time() * 1000)))

    def on_pong(self, data):
        print("pong", data)
        if not data:
            self.ping(str(round(datetime.datetime.now().timestamp() * 1000)))

    def initialize(self):
        """为每个请求初始化"""
        self.current_user = None

    def prepare(self):
        """请求前置操作"""
        pass

    def open(self):
        """建立连接"""
        log.info(f"建立连接: [{self.request.remote_ip}]-[{datetime.datetime.now()}]")
        self.set_nodelay(True)  # 设置无延迟
        # 单位毫秒,上下浮动50%
        self.event_loop = PeriodicCallback(callback=self.send_message, callback_time=1000, jitter=0.5)
        self.event_loop.start()

    def on_message(self, message):
        """接收前端信息"""
        print("msg:", message)

    def on_close(self):
        """连接断开"""
        log.info(f"连接断开: [{self.request.remote_ip}]-[{datetime.datetime.now()}]")
        self.event_loop.stop()

    async def send_message(self):
        """发送信息"""
        await asyncio.sleep(0.5)
        if self.ws_connection is None or self.ws_connection.is_closing():
            self.close()
            return
        await self.write_message(str(datetime.datetime.now()))


class Main:
    def __init__(self, debug=False):
        self.debug = debug
        self.urls = [
            (r"/ws", MyWsHandler),
        ]

    def mkApp(self):
        return Application(
            self.urls,
            debug=self.debug,
            websocket_ping_interval=5,  # 间隔5秒发送一次ping帧,第一次发送为触发的5s后
            websocket_ping_timeout=20   # 每次 ping 操作重置时间超时时间,若超时则断开连接,默认3次 ping 或 30s 断开
        )

    async def admin(self, host, port):
        app = self.mkApp()
        app.listen(address=host, port=port)
        await asyncio.Event().wait()

    def run(self, host, port):
        log.info(f"启动服务: {host}:{port}")
        asyncio.run(self.admin(host=host, port=port))


if __name__ == '__main__':
    Main(debug=True).run(host="0.0.0.0", port=12001)
    # ws://127.0.0.1:12001/ws

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要使用 Tornado 搭建 WebSocket 客户端,可以按照以下步骤进行: 1. 安装 Tornado 使用 pip 安装 Tornado: ``` pip install tornado ``` 2. 编写客户端代码 在 Tornado 中,可以使用 `websocket.WebSocketClientConnection` 类来创建 WebSocket 客户端连接。以下是一个简单的例子: ```python import tornado.websocket import tornado.ioloop class MyWebSocketClient(tornado.websocket.WebSocketClientConnection): def on_message(self, message): print("Received message: {}".format(message)) def on_close(self): print("Connection closed") if __name__ == "__main__": ws_url = "ws://example.com/socket" ws_client = MyWebSocketClient(ws_url) ws_client.connect() tornado.ioloop.IOLoop.current().start() ``` 在这个例子中,我们创建了一个名为 `MyWebSocketClient` 的类,继承自 `WebSocketClientConnection`。我们重载了 `on_message` 和 `on_close` 方法来处理消息和关闭事件。在 `main` 函数中,我们创建了一个 `MyWebSocketClient` 对象,并调用了 `connect` 方法来建立连接。最后,我们启动了 Tornado 的 I/O 循环。 3. 运行客户端代码 运行客户端代码,即可建立 WebSocket 连接并接收来自服务器的消息。如果你想发送消息,可以使用 `write_message` 方法。例如,在 `MyWebSocketClient` 类中添加以下方法: ```python def send_message(self, message): self.write_message(message) ``` 然后,在 `main` 函数中调用 `ws_client.send_message("hello")` 就可以发送消息了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aiden_SHI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值