Flask-SocketIO Redis订阅

我正在使用https://github.com/miguelgrinberg/Flask-

SocketIO来实现WebSocket服务器。

我需要从另一个进程(仅订阅)接收消息,并为特定房间中的客户端发出消息。

但是,当我尝试发送消息时,出现此错误:

无法将消息发送到家庭会议室:在请求上下文之外工作。

这是我的代码:

from flask import Flask, request

from 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

回到顶部