Compartilhamento de tecnologia

Estrada de aprendizagem FastAPI (44) WebSockets

2024-07-12

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

Nossa análise anterior foi toda baseada em solicitações http, então se os websockets puderem suportá-lo, a resposta é sim, vamos dar uma olhada em como implementá-lo.

  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}")

Na verdade, é muito simples. Escrevemos uma interface para receber mensagens no back end. Quando uma mensagem chega, processamos a mensagem. Antes ela era tratada por http, mas agora é websocket. Devolvemos a mensagem recebida diretamente para o front end.

Vamos dar uma olhada no efeito:

Desta forma, simplesmente implementamos a função de um websocket. Então temos uma mensagem específica e encerramos o chat, como lidar com isso?

  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}")

O código do front-end não foi alterado, apenas o back-end foi modificado.

Na verdade, é muito simples implementar a comunicação websocket aqui.

Claro que também podemos usá-lo em solicitações

  • Depende
  • Segurança
  • Biscoito
  • Cabeçalho
  • Caminho
  • Consulta

Podemos ver o seguinte exemplo de escrita de back-end simples

  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}")

Embora tenhamos simplesmente implementado o backend, podemos ver que fastapi tem um bom suporte para websocket