Twisted 与 Tornado 中的 WebSocket 连接问题及解决方案

ops/2024/9/25 17:13:09/

在这里插入图片描述

1、问题背景

项目中我们需要通过 Tornado HTTP 处理程序建立WebSocket连接,该连接需要处理多个用户请求,并且将从外部服务器获取的数据存储到数据库中。我们尝试了以下实现:

python">from twisted.internet import reactor
from autobahn.websocket import WebSocketClientFactory, WebSocketClientProtocol, connectWS
from tornado.options import define, options, parse_command_lineclass IndexHandler(tornado.web.RequestHandler):@tornado.web.asynchronousdef get(self):self.write("This is your response")factory = WebSocketClientFactory("ws://localhost:7096")factory.protocol = BridgeSocketconnectWS(factory)self.finish()reactor.run()class BridgeSocket(WebSocketClientProtocol):def sendHello(self):self.sendMessage("rails")def onOpen(self):self.sendHello()def onMessage(self, msg, binary):print "Got echo: " + msgdef onClose(wasClean,code,reason):print "GETTING CLOSE CONNECTION"print str(wasClean)+" ---"+str(code)+"---"+str(reason)reactor.stop()

但是,reactor.run()会阻止对Tornado Web服务器的进一步HTTP请求,如果我们在WebSocket工作完成后立即调用reactor.stop(),又会发现无法重新启动reactor。

2、解决方案

为了在Tornado中运行AutobahnPython的WebSocket客户端,我们需要使用Twisted-Tornado集成(“Twisted on Tornado”)。这个库允许我们在Tornado中运行Twisted reactor循环。

以下是如何使用Twisted on Tornado来解决问题的步骤:

  1. 安装Twisted on Tornado:
pip install twisted-tornado
  1. 在你的Tornado应用程序中导入Twisted on Tornado:
python">from twisted.internet import reactor
from twisted.internet.defer import Deferred
from tornado.ioloop import IOLoop
  1. 在你的Tornado HTTP处理程序中,使用Twisted on Tornado的reactor来运行WebSocket客户端:
python">def main():reactor.suggestThreadPoolSize(1)  # Increase threadpool size for multiple persistent connectionsIOLoop.instance().run(True)reactor.callWhenRunning(main)
  1. 修改你的WebSocket客户端协议类,使其继承自Twisted的WebSocketClientFactory:
python">class BridgeSocket(WebSocketClientFactory):def buildProtocol(self, addr):return BridgeSocketProtocol()class BridgeSocketProtocol(WebSocketClientProtocol):def sendHello(self):self.sendMessage("rails")def onOpen(self):self.sendHello()def onMessage(self, msg, binary):print "Got echo: " + msgdef onClose(self, wasClean, code, reason):print "GETTING CLOSE CONNECTION"print str(wasClean)+" ---"+str(code)+"---"+str(reason)reactor.stop()
  1. 在你的Tornado应用程序中,使用Twisted on Tornado的reactor来连接到WebSocket服务器:
python">from twisted.internet import reactordef connect_to_websocket():factory = BridgeSocket()reactor.connectTCP("localhost", 7096, factory)reactor.callWhenRunning(connect_to_websocket)

这样,我们就可以在Tornado中使用AutobahnPython的WebSocket客户端,而不会阻止对Tornado Web服务器的进一步HTTP请求。


http://www.ppmy.cn/ops/23641.html

相关文章

ssh连接自动断开的几种可能

SSH连接自动断线是一个常见问题,通常由多种原因引起,包括网络不稳定、SSH配置不当、服务器设置、防火墙规则等。以下是几种可能的解决方法,仅供参考: 1. 设置SSH连接参数:使用 -vvv 参数运行SSH命令以获取详细的调试信…

计算机考研到双非院校的性价比分析

我选择读研为自己过渡深造,本科期间没有做过项目和实验,读研期间好好搞 很多公司更加看中的是个人硬实力...双非研究生出去找工作机会也并不少,只要实力够,学历加成一下,机会还是非常多的 研究生的学历算是一个门槛&…

2024.4.29力扣刷题记录-数组篇记录4

目录 一、697. 数组的度 二、448. 找到所有数组中消失的数字 三、442. 数组中重复的数据 四、 41. 缺失的第一个正数 五、485. 最大连续 1 的个数 一、697. 数组的度 哈希表 class Solution:def findShortestSubArray(self, nums: List[int]) -> int:# 哈希表# 找出最…

C++ 小游戏:战斗之旅

一、游戏名称:战斗之旅 游戏规则 角色选择:玩家可以选择不同的角色,每个角色都有不同的属性和技能。商城:玩家可以访问商城购买不同的装备,包括武器和回复物品。战斗:玩家可以与其他角色进行战斗。在战斗…

UE_反射系统(虚幻编译系统)

UE_反射系统(虚幻编译系统) UCLASS、UFUNCTION、UPROPERTY UCLASS 宏的有效关键字 https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Classes/Specifiers/ When declaring classes, Class Specifiers can be added to the declar…

LLM应用实战:当KBQA集成LLM(二)

1. 背景 又两周过去了,本qiang~依然奋斗在上周提到的项目KBQA集成LLM,感兴趣的可通过传送门查阅先前的文章《LLM应用实战:当KBQA集成LLM》。 本次又有什么更新呢?主要是针对上次提到的缺点进行优化改进。主要包含如下方面&#…

小程序中如何快速给分类添加商品

​快速在分类下面上传商品,并且能够设置商品顺序,关系到运营效率的高低。下面就具体介绍如何快速在某个分类下面设置商品。 一、在商品管理处,查询某个分类下面的商品。 进入小程序管理员后台->商品管理,点击分类输入框&…

Unity Meta Quest MR 开发(七):使用 Stencil Test 模板测试制作可以在虚拟与现实之间穿梭的 MR 传送门

文章目录 📕教程说明📕Stencil Test 模板测试📕Stencil Shader📕使用 Unity URP 渲染管线设置模板测试⭐Render Pipeline Asset 与 Universal Renderer Data⭐删除场景中的天空盒⭐设置虚拟世界的层级 Layer⭐设置模板测试 &#…