Websockets 无法使用蓝图在 Quart 中工作

问题描述 投票:0回答:1

`我正在尝试使用蓝图初始化与 Broker 类的 websocket 连接,但似乎它没有收到任何响应,仅返回 400 错误:

WebSocket 错误: 错误 { target: WebSocket, isTrusted: true, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false,composed: false, … } 气泡:假 取消气泡:假 可取消:假 组成:假 当前目标:空 默认阻止: false 事件阶段:0 ExplicitOriginalTarget: WebSocket { url: "ws://dev.localhost:5000/ws", readState: 3, bufferedAmount: 0, … } 是否受信任: true 原始目标:WebSocket { url:“ws://dev.localhost:5000/ws”,readyState:3,bufferedAmount:0,... } 返回值: true srcElement: WebSocket { url: "ws://dev.localhost:5000/ws", readState: 3, bufferedAmount: 0, … } 目标:WebSocket { url:“ws://dev.localhost:5000/ws”,readyState:3,bufferedAmount:0,... } 时间戳:905322 类型:“错误”

应用程序。 py:

if __name__ == "__main__":

    from routes.ws_bp import ws_bp as wbp

    app.register_blueprint(wbp)

ws.py:

import asyncio
from typing import AsyncGenerator
from quart import Quart

class Broker:
    def __init__(self) -> None:
        self.connections = set()

async def publish(self, message: str) -> None:
    for connection in self.connections:
        await connection.put(message)

async def subscribe(self) -> AsyncGenerator[str, None]:
    connection = asyncio.Queue()
    self.connections.add(connection)
    try:
        while True:
            yield await connection.get()
    finally:
        self.connections.remove(connection)
broker = Broker()

ws_bp.py:

from quart import Blueprint, websocket
import asyncio
from services.ws import broker

ws_bp = Blueprint('ws_bp', __name__)


async def _receive() -> None:
    while True:
        message = await websocket.receive()
        await broker.publish(message)


@ws_bp.websocket('/ws')
async def ws() -> None:
    try:
        task = asyncio.ensure_future(_receive())
        async for message in broker.subscribe():
            await websocket.send(message)
    finally:
        task.cancel()
        await task

反应前端服务器:

const { sendMessage, lastMessage, readyState } = useWebSocket('ws://dev.localhost:5000/ws', {
  onOpen: () => {
    console.log('WebSocket connection established.');
  },
  onMessage: (message) => {
    console.log('Received message:', message);
  },
  onClose: () => {
    console.log('WebSocket connection closed.');
  },
  onError: (error) => {
    console.error('WebSocket error:', error);
  },
  shouldReconnect: (closeEvent) => true,
});
return (
     <div>
     <button onClick={() => sendMessage('Hello from client!')}>Send Message</button>
    {lastMessage ? <p>Last message: {lastMessage.data}</p> : <p>No messages received yet. </p>}
    </div> )`
websocket blueprint quart
1个回答
0
投票

这可能不是您正在寻找的答案,但它可以帮助某人,或者至少有助于诊断问题。我遇到了类似的问题,然后我就剥离了我的应用程序。

import quart_flask_patch

from typing import Any
from quart import Quart
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from .config import configenv
from quart_cors import cors, route_cors
from quart_rate_limiter import RateLimiter


def create_app(configname:str , namespaces: list) -> Quart:
    '''Create app module and initialization of core packages'''
    app: Any = Quart(__name__)
    app.config.from_object(configenv[configname])

    from app import models
    db.init_app(app)
    migrate.init_app(app, db, render_as_batch=True)
    rate_limiter.init_app(app)
    
    # cors(app) # !!! This was my mistake !!!
    
    from app.api import api as api_blueprint
    from app.webhooks import webhook as webhook_blueprint

    app.register_blueprint(api_blueprint)
    app.register_blueprint(webhook_blueprint, url_prefix='/webhook')
    app.register_blueprint(rq_dashboard.blueprint, url_prefix="/api/rq")

    return app

就我而言,我注意到这是一个 CORS(跨源资源共享)问题。尝试注释 cors,如果必须使用 cors,请确保正确实现它。如果您使用 quart_cors 包,请确保使用 Route_cors 模块将 cors 限制为路由。

from quart_cors import route_cors
© www.soinside.com 2019 - 2024. All rights reserved.