【问题标题】:Socketio implementation with FastApi and React使用 FastApi 和 React 实现 Socketio
【发布时间】:2021-12-08 11:47:14
【问题描述】:

我有以下技术栈

  1. FastApi - 后端
  2. 反应 - 前端

并且想要实现socketio(不是FastApi提供的Websockets)。它在 FastApi 和 Socketio 中都缺少文档

【问题讨论】:

    标签: python reactjs websocket socket.io fastapi


    【解决方案1】:

    根据需要,我们将python-socketio 用于后端套接字服务器,在反应时我们将使用socket.io-client。 安装完成后,我们需要设置一个套接字服务器。

    后端实现

    # socket.py
    
    def handle_connect(sid, environ):
        logger.info(f"Socket connected with sid {sid}")
    
    class SocketManager:
        def __init__(self, origins: List[str]):
            self.server = socketio.AsyncServer(
                cors_allowed_origins=origins,
                async_mode="asgi",
                logger=True,
                engineio_logger=True,
            )
            self.app = socketio.ASGIApp(self.server)
    
        @property
        def on(self):
            return self.server.on
    
        @property
        def send(self):
            return self.server.send
    
        def mount_to(self, path: str, app: ASGIApp):
            app.mount(path, self.app)
    
    
    socket_manager = SocketManager(settings.origins)
    socket_manager.on("connect", handler=handle_connect)
    

    仔细检查您的 cors 来源。您也可以使用socket_manager.on 添加其他处理程序。

    #main.py
    
    from socket import 
    
    app = FastAPI(...)
    socket_manager.mount_to("/ws", app)
    

    前端实现 集成的基本代码很简单

    import { io } from "socket.io-client";
    
    const socket = io("ws://localhost:8000", {{ path: "/ws/socket.io/", transports: ['websocket', 'polling'] }});
    socket.on("connect", () => { console.log("Connected", socket.id) }); 
    socket.on("response", () => { console.log("Response", socket.id) });  
    socket.on("message", data => { console.log(data) });
    

    对于我的项目,我为此创建了一个上下文,如下所示

    import React, { createContext, useContext, useEffect, useState } from 'react';
    
    import { io } from "socket.io-client";
    import { useToastContext } from './ToastContext';
    
    
    export const SocketContext = createContext()
    
    
    export const SocketProvider = ({ children, uri, options }) => {
        const [socketIo, setSocketIo] = useState()
        const { sendToast } = useToastContext();
    
        useEffect(() => {
            const socket = io(uri, options);
            socket.on("connect", () => { console.log("Connected", socket.id) });
            socket.on("response", () => { console.log("Response", socket.id) });
            socket.on("message", data => { 
                sendToast(data)
            });
            setSocketIo(socket)
        }, [])
    
        return (
            <SocketContext.Provider value={socketIo}>
                {children}
            </SocketContext.Provider>
        )
    }
    
    export const useSocket = () => {
        return useContext(SocketContext)
    }
    

    现在终于可以从服务器向客户端发送消息了

    socket_manager.send("Hello World")
    

    值得注意的点

    • CORS 来源应该是完全相同的,如果它是来自前端的 http://localhost:3000,那么它应该是 http://localhost:3000 而不是 http://localhost:3000/。寻找反斜杠
    • socketio 文档还说transports: ['websocket', 'polling'] 是默认值,但是当我删除它时。它给了我cors错误。文档可能已过期。

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 2019-12-10
      • 2014-01-04
      • 1970-01-01
      • 2022-07-15
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2020-11-24
      相关资源
      最近更新 更多