Compartir tecnología

Camino de aprendizaje FastAPI (44) WebSockets

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Todo nuestro análisis anterior se basó en solicitudes http, por lo que si websockets puede admitirlo, la respuesta es sí, echemos un vistazo a cómo implementarlo.

  1. from fastapi import WebSocket, FastAPI
  2. from fastapi.responses import HTMLResponse
  3. app = FastAPI()
  4. html = """
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <title>Chat</title>
  9. </head>
  10. <body>
  11. <h1>WebSocket 聊天</h1>
  12. <form action="" onsubmit="sendMessage(event)">
  13. <input type="text" id="messageText" autocomplete="off"/>
  14. <button>Send</button>
  15. </form>
  16. <ul id='messages'>
  17. </ul>
  18. <script>
  19. var ws = new WebSocket("ws://localhost:8000/ws");
  20. ws.onmessage = function(event) {
  21. var messages = document.getElementById('messages')
  22. var message = document.createElement('li')
  23. var content = document.createTextNode(event.data)
  24. message.appendChild(content)
  25. messages.appendChild(message)
  26. };
  27. function sendMessage(event) {
  28. var input = document.getElementById("messageText")
  29. ws.send(input.value)
  30. input.value = ''
  31. event.preventDefault()
  32. }
  33. </script>
  34. </body>
  35. </html>
  36. """
  37. @app.get("/")
  38. async def get_page():
  39. return HTMLResponse(html)
  40. @app.websocket("/ws")
  41. async def websocket_endpoint(websocket: WebSocket):
  42. await websocket.accept()
  43. while True:
  44. data = await websocket.receive_text()
  45. await websocket.send_text(f"接收到的消息是:{data}")

De hecho, es muy simple. Escribimos una interfaz para recibir mensajes en el back-end. Cuando llega un mensaje, lo procesamos antes, pero ahora es websocket. Devolvimos el mensaje recibido directamente al front-end.

Echemos un vistazo al efecto:

De esta forma, simplemente implementamos la función de un websocket. Entonces tenemos un mensaje específico y cerramos el chat, ¿cómo lidiar con eso?

  1. # 接收特定的消息后,终止该聊天
  2. @app.websocket("/ws")
  3. async def websocket_endpoint(websocket: WebSocket):
  4. await websocket.accept()
  5. while True:
  6. data = await websocket.receive_text()
  7. if data == "bye":
  8. await websocket.send_text(f"请注意:窗口即将关闭")
  9. await websocket.send_text("窗口已关闭")
  10. await websocket.close()
  11. break
  12. else:
  13. await websocket.send_text(f"接收到的消息是:{data}")

El código de front-end no se ha cambiado, solo se ha modificado el back-end.

De hecho, es muy sencillo implementar la comunicación websocket aquí.

Por supuesto también podemos usarlo en solicitudes.

  • Depende
  • Seguridad
  • Galleta
  • Encabezamiento
  • Camino
  • Consulta

Podemos ver el siguiente ejemplo de una escritura de backend simple.

  1. # 使用多种参数,比如获取cookie等
  2. from typing import Optional
  3. from fastapi import Cookie, Query, status, Depends
  4. async def get_cookie_or_token(
  5. websocket: WebSocket,
  6. session: Optional[str] = Cookie(None),
  7. token: Optional[str] = Query(None),
  8. ):
  9. if session is None and token is None:
  10. await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
  11. return session or token
  12. @app.websocket("item/ws")
  13. async def websocket_endpoint(
  14. websocket: WebSocket,
  15. q: Optional[int] = None,
  16. cookie_or_token: str = Depends(get_cookie_or_token),
  17. ):
  18. await websocket.accept()
  19. while True:
  20. data = await websocket.receive_text()
  21. await websocket.send_text(
  22. f"Session cookie or query token value is: {cookie_or_token}"
  23. )
  24. if q is not None:
  25. await websocket.send_text(f"parameter q is: {q}")
  26. await websocket.send_text(f"Message text was: {data}, for : {q}")

Aunque simplemente hemos implementado el backend, podemos ver que fastapi tiene un buen soporte para websocket.