Flask-SocketIO Redis订阅
我正在使用https://github.com/miguelgrinberg/Flask-
SocketIO来实现WebSocket服务器。
我需要从另一个进程(仅订阅)接收消息,并为特定房间中的客户端发出消息。
但是,当我尝试发送消息时,出现此错误:
无法将消息发送到家庭会议室:在请求上下文之外工作。
这是我的代码:
from flask import Flask, requestfrom flask_socketio import SocketIO, join_room, leave_room, send, rooms
import json
import eventlet
import logging
import redis
import threading
FORMAT = '%(asctime)-15s - %(message)s'
logging.basicConfig(format=FORMAT)
log = logging.getLogger(__name__)
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode='eventlet')
.
.
.
def _send_task_message():
try:
send(json.dumps({"type":"UPDATE_TASK"}), room='home')
except Exception as e:
log.error('Could not send message to home room: %s' % str(e))
class Listener(threading.Thread):
def __init__(self, r, channels):
threading.Thread.__init__(self)
self.daemon = True
self.redis = r
self.pubsub = self.redis.pubsub()
self.pubsub.psubscribe(channels)
def work(self, item):
if isinstance(item['data'], bytes):
try:
msg = item['data'].decode('utf-8')
decode_msg = json.loads(msg)
if decode_msg['type'] == 'UPDATE_TASK':
_send_task_message()
except ValueError as e:
log.error("Error decoding msg to microservice: %s", str(e))
def run(self):
for item in self.pubsub.listen():
self.work(item)
if __name__ == '__main__':
r = redis.Redis()
client = Listener(r, ['/bobguarana/socketio'])
client.start()
socketio.run(debug=True, app=app, port=8080)
回答:
我解决了将应用程序作为参数传递给类并按照错误描述的建议使用它的上下文,但是名称空间也是必需的:
class Listener(threading.Thread): def __init__(self, r, channels, app):
threading.Thread.__init__(self)
self.daemon = True
self.redis = r
self.pubsub = self.redis.pubsub()
self.pubsub.psubscribe(channels)
self.app = app
def work(self, item):
with app.app_context():
if isinstance(item['data'], bytes):
try:
msg = item['data'].decode('utf-8')
decode_msg = json.loads(msg)
if decode_msg['type'] == 'UPDATE_TASK':
send(json.dumps({"type":"UPDATE_TASK"}), room='home', namespace='/')
#_send_task_message()
except ValueError as e:
log.error("Error decoding msg to microservice: %s", str(e))
def run(self):
for item in self.pubsub.listen():
self.work(item)
if __name__ == '__main__':
r = redis.Redis()
client = Listener(r, ['/bobguarana/socketio'], app)
client.start()
socketio.run(debug=True, app=app, port=8080)
以上是 Flask-SocketIO Redis订阅 的全部内容, 来源链接: utcz.com/qa/430493.html