websocket and fastapi
This project demonstrates how to use socket.io with FastAPI and React
https://github.com/jrdeveloper124/socketio-app/tree/main
You can use WebSockets with FastAPI.
https://fastapi.tiangolo.com/advanced/websockets/
https://stackoverflow.com/questions/71827145/broadcasting-a-message-from-a-manager-to-clients-in-websocket-using-fastapi
How to send messages from server to client in a Python WebSockets server, AFTER initial handshake?
https://stackoverflow.com/questions/74988529/how-to-send-messages-from-server-to-client-in-a-python-websockets-server-after
import asyncio import datetime from typing import Iterator import websockets import random websocket_connections = set() sock_port = 8000 sock_url = 'localhost' global_socket = lambda: None async def register(websocket): print('register event received') websocket_connections.add(websocket) # Add this client's socket global_socket = websocket async def poll_log(): await asyncio.sleep(0.3) # Settle while True: await asyncio.sleep(0.3) # Slow things down # Send a dynamic message to the client after random delay r = random.randint(1, 10) if (r == 5): # Only send 10% of the time a_msg = "srv -> cli: " + str(random.randint(1,10000)) print("sending msg: " + a_msg) websockets.broadcast(websocket_connections, a_msg) # Send to all connected clients async def main(): sock_server = websockets.serve(register, sock_url, sock_port) await asyncio.sleep(0.3) # Start up time async with sock_server: await poll_log() if __name__ == "__main__": print("Websockets server starting up ...") asyncio.run(main())
websocket-example
https://github.com/ustropo/websocket-example/tree/main
Scaling WebSocket applications
https://unfoldai.com/fastapi-and-websockets/
通过http post API发送数据到websocket数据通道,达到客户端。
import aioredis from fastapi import FastAPI, WebSocket app = FastAPI() async def get_redis(): redis = await aioredis.create_redis_pool("redis://localhost") return redis @app.websocket("/ws/redis/{channel}") async def websocket_endpoint(websocket: WebSocket, channel: str): await websocket.accept() redis = await get_redis() try: channel = await redis.subscribe(channel) async for message in channel[0].iter(): await websocket.send_text(message.decode()) finally: await redis.unsubscribe(channel) redis.close() await redis.wait_closed() @app.post("/publish/{channel}") async def publish(channel: str, message: str): redis = await get_redis() await redis.publish(channel, message) return {"message": "Published"}
上面使用redis做消息中介, 来链接 HTTP api 和 websocket数据通道。
下面这个例子展示了,使用异步消息队列也是一种可行方案。
https://github.com/fanqingsong/fastapi-websockets-aiohttp-demo
import asyncio import uvicorn from fastapi import FastAPI, WebSocket from client import WebClient from weather import WeatherClient client = WebClient() api = FastAPI() @api.on_event('shutdown') def shutdown(): client.shutdown() @api.get("/") async def read_root(): return {"Hello": "World"} async def send_weather_data(websocket: WebSocket, weather_client: WeatherClient, data: dict): while True: weather = await weather_client.weather(data) await websocket.send_json(weather.dict()) await asyncio.sleep(15) @api.websocket("/ws/weather") async def read_websocket(websocket: WebSocket): await websocket.accept() weather_client = WeatherClient(client) queue = asyncio.queues.Queue() async def read_from_socket(): async for data in websocket.iter_json(): queue.put_nowait(data) async def send_data(): data = await queue.get() send_task = asyncio.create_task(send_weather_data(websocket, weather_client, data)) while True: data = await queue.get() if data: print(f'Cancelling existing task since got new event={data}') send_task.cancel() send_task = asyncio.create_task(send_weather_data(websocket, weather_client, data)) await asyncio.gather(read_from_socket(), send_data()) if __name__ == '__main__': uvicorn.run(api)
useEffect
https://www.ruanyifeng.com/blog/2020/09/react-hooks-useeffect-tutorial.html
出处:http://www.cnblogs.com/lightsong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。