代码之家  ›  专栏  ›  技术社区  ›  Max Shylnikov

通过websocket连接FastAPI和react admin

  •  0
  • Max Shylnikov  · 技术社区  · 3 年前

    我对react and react管理员有点陌生。 任务很简单,就是通过websocket将FastAPI服务器与react管理应用程序连接起来。我想我必须以某种方式创建websocket数据提供程序。

    用于react admin App.tsx

    
    export const App = () => (
    
        <Admin
            dataProvider={dataProvider}
        >
            <Resource name="" list={} show={} />
        </Admin>
    );
    

    dataProvider.tsx

    import jsonServerProvider from 'ra-data-json-server';
    
    const URL = 'http://127.0.0.1:8000/'
    
    
    export const dataProvider = jsonServerProvider(
        URL
    );
    

    当我简单地将http更改为ws时,会出现错误 url scheme 'ws' is not supported 因为它使用fetch(),而fetch(。

    我认为不需要我的FastAPI代码,但不管怎样:

    @router.websocket('/ws/send-data/')
    async def ws_send_users(websocket: WebSocket):
        print('2 in ws_send_users')
        await websocket.accept()
        while True:
            await websocket.send_text('text1')
            await asyncio.sleep(0.25)
    
    
    @router.websocket('/ws/send-data/{user_inner}')
    async def ws_send_user(websocket: WebSocket,
                           user_inner: str = None):
        print('1 in ws_send_user')
    
        await websocket.accept()
        while True:
            if not user_inner:
                return await ws_send_users(websocket)
            await websocket.send_text('text2')
            await asyncio.sleep(0.25)
    

    默认情况下 http 它非常完美: ws_send_user 在我们想要的时候被调用 show react admin中的用户,以及 ws_send_users 在我们想要的时候被调用 list 用户

    这段代码创建了websocket连接并获得了事件,但我认为它有问题。无论如何,IDK如何将其与react管理接口连接(列表和显示选项)。

    export const App = () => (
    
        <Admin
            dataProvider={useEffect(() => {
                const WS = new WebSocket(`ws://127.0.0.1:8000/ws/send-data/`);
                WS.onmessage = e => {
                    console.log('el', e.data)
                    e.data && !(USERS.includes(e.data)) ? USERS.push(e.data) : null;
                }
    
            })}
        >
            <Resource name="" list={} show={} />
        </Admin>
    );
    

    目的是获取用户列表 列表 并且每个单独的用户 显示 通过一些反应管理魔法,所以如果你有经验,请帮助我。

    0 回复  |  直到 3 年前
        1
  •  0
  •   Max Shylnikov    3 年前

    好的,我想我已经连接好了。由于我是JS和React的新手,我想提高代码的质量

    class WebSocketDataProvider {
        constructor() {
            this.apiUrl = `ws://yourhost:yourport/ws/send-data/`;
            this.socket = new WebSocket(this.apiUrl);
            this.socket.addEventListener('open', this.handleSocketOpen);
            this.socket.addEventListener('message', this.handleSocketMessage);
            this.socket.addEventListener('error', this.handleSocketError);
            this.socket.addEventListener('close', this.handleSocketClose);
        }
    
        handleSocketOpen = () => {
            console.log('WebSocket connection is open');
        };
    
        handleSocketMessage = (event) => {
            this.getList(event);
        };
    
        handleSocketError = (event) => {
            console.log('HandleSocketError', event)
        };
    
        handleSocketClose = (event) => {
            console.log('HandleSocketClose', event)
        };
    
        getList = (event) => {
    
            return new Promise((resolve, reject) => {
                const handleResponse = (event) => {
                    const parsedResponse = JSON.parse(event.data);
                    let response = {
                        data: [],
                        total: Object.keys(parsedResponse).length,
                    }
                    Object.entries(parsedResponse).forEach((key, value) => {
                        let obj = {
                            id: key[0],
                            urls: key[1],
                        }
                        response.data.push(obj);
                    });
                    resolve(response);
                    this.socket.removeEventListener('message', handleResponse);
                }
                this.socket.addEventListener('message', handleResponse);
            });
        };
    
        getOne = (event) => {
    
            return new Promise((resolve, reject) => {
                const handleResponse = (event) => {
                    const parsedResponse = JSON.parse(event.data);
                    const href = location.href.split('/');
                    const length = href.length
                    const userId = href[length - 2]
                    let response = {
                        data:
                        {
                            id: userId,
                            urls: parsedResponse.userId,
                        }
                    }
    
                    resolve(response);
                    this.socket.removeEventListener('message', handleResponse);
                }
                this.socket.addEventListener('message', handleResponse);
            });
        };
    }
    
    const dataProvider = new WebSocketDataProvider;
    export default dataProvider;