socket python 收 发 线程_Python-Flask SocketIO从线程发送消息:不总是有效的

我正处于从客户那里收到消息的情况。在处理该请求的函数(@socketio.on)中,我想调用一个完成一些繁重工作的函数。这不应该导致阻塞主线程,并且认为一旦完成工作,就会通知客户机。因此,我开始了一个新的线程。

现在我遇到了一个非常奇怪的行为:

消息永远不会到达客户机。但是,代码到达发送消息的特定位置。

更令人惊讶的是,如果线程中除了发送给客户机的消息之外没有发生任何事情,那么答案实际上会找到通向客户机的路。

总而言之:

如果在发送消息之前发生了一些计算密集型的事情,则它不会被传递,否则就是。

就像上面说的here和here一样,从线程向客户端发送消息根本不是问题:In all the examples shown until this point the server responds to an event sent by the client. But for some applications, the server needs to be the originator of a message. This can be useful to send notifications to clients of events that originated in the server, for example in a background thread.

这是一个示例代码。当移除注释锐器(#)时,消息('foo from thread')无法到达客户端,否则它会找到。from flask import Flask

from flask.ext.socketio import SocketIO, emit

app = Flask(__name__)

socketio = SocketIO(app)

from threading import Thread

import time

@socketio.on('client command')

def response(data):

thread = Thread(target = testThreadFunction)

thread.daemon = True

thread.start()

emit('client response', ['foo'])

def testThreadFunction():

# time.sleep(1)

socketio.emit('client response', ['foo from thread'])

socketio.run(app)

我使用的是Python 3.4.3,Flask 0.10.1,Flask-socketio1.2,eventlet 0.17.4。

此示例可以复制并粘贴到.py文件中,并且行为可以立即复制。

有人能解释一下这种奇怪的行为吗?

更新

这似乎是一个小插曲。如果我这样做了:socketio = SocketIO(app, async_mode='threading')

它强制应用程序不使用eventlet,尽管它已安装。

但是,对于我来说,这不是一个适用的解决方案,因为使用“线程”作为异步模式拒绝接受二进制数据。每次我从客户端向服务器发送二进制数据时,它都会说:

WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance.

第三个选项,使用gevent作为异步模式对我不起作用,而且gevent还不支持python 3。

还有其他建议吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 课程设计基于Socket作为服务器与传感器通讯手段的家庭能源管理系统python源码+部署说明.zip 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能。 欢迎下载,欢迎交流,互相学习进步! 特性 以Socket作为服务器与传感器通讯手段 多传感器支持 友好的Web用户界面 可以控制每一个传感器的开关面板 清晰的实时动态数据分析大屏幕 警告 程序说崩就崩,我没有做任何与鲁棒性有关的考虑与设计。 哪怕程序正常跑起来了也不能说明是神明在保佑。我是坚定的唯物主义者。 别动代码,除非您知道自己在干什么。 以上三条纯属娱乐。不过程序确实挺粗糙的就对了。 项目组成 这个项目由以下三个大模块组成: 1. 后端通信模块 2. 数据处理中间件 3. WEB服务器与相应前端 根据课设要求,现在主要介绍后端通信模块。 后端通信模块 SocketServer.py 模块作用 SocketServer.py为通信模块的服务器端,负责接传感器数据。 模块实现 服务器端采用了socketserver库,该库封装了socket模块,使得每个拨入的连接将被传入一个新的线程处理,从而实现多传感器通信的功能。 socket模块 socket模块运作模式如下: 1. 定义连接,端口族等(这些功能已经被封装,将在编程时默认调用) 2. 将程序绑定至指定端口 3. 监听进入阻塞状态 4. 当呼叫传入时,切换为accept状态 5. 接受数据,填充缓冲区 6. 循环程序,再次填充缓冲区,输出数据 SocketClient.py 模块作用 SocketServer.py为通信模块的传感器端,负责模拟发送传感器数据。 模块详情 模块允许创建多个线程来模拟多个传感器同时呼入的情况。 协议文档 发送 一个传感器应当发送这样的 json : ```json { "type": "data", "id": 1, "sn": "DNPLK11FNK", "power": "1200", "state": "on", "time": 1639451655.1565 } ``` type:定义了数据类型,目前仅定义了“data”。 id:传感器id,为整形类型 sn:传感器序列号 power:传感器检测到的功率 state:传感器目前的状态 on:表示传感器处于开启状态 suspend:表示传感器正忙,处于挂起状态 off:表示传感器处于关闭状态。当传感器处于关闭或挂起状态时,传感器将不发送当前功率。 time:当前时间戳,为double类型 接 传感器将在每个通信轮询中接受来自服务器的命令,并会按照服务器命令切换状态。 ```json { "result": "ok" } ``` 当服务器返回ok时,传感器将在下一个通讯轮询切换为打开状态。 ```json { "result": "off" } ``` 当服务器返回off时,传感器将在下两个通讯轮询切换为suspend状态,随后切换为off状态 当传感器连续两个周期不返回任何数据,传感器将自动挂起并关闭。 数据处理部分与WEB部分 数据处理负责将后端数据写入sqlite数据库,并计算相关数据供前端直接调用 WEB部分负责创建相应的接口与前端页面,调用并显示页面与相关数据,并允许控制 WEB服务器部分采用flask框架,采用Pywebio进行页面生,echarts生成实时图形。 运行项目 本项目完全使用Python构成,解释器版本为3.10。您可以像运行普通Python程序一样运行本项目。 1. 将本仓库克隆到本地 2. 安装本项目使用的所有依赖库 3. 运行根目录下的main.py

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值