Κοινή χρήση τεχνολογίας

FastAPI Learning Road (44) WebSockets

2024-07-12

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

Η προηγούμενη ανάλυσή μας βασίστηκε όλη σε αιτήματα http, οπότε αν τα websockets μπορούν να την υποστηρίξουν, η απάντηση είναι ναι, ας ρίξουμε μια ματιά στον τρόπο εφαρμογής της.

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

Στην πραγματικότητα, είναι πολύ απλό. Γράφουμε μια διεπαφή για τη λήψη μηνυμάτων στο πίσω μέρος του μηνύματος. Επιστρέψαμε το μήνυμα που λάβαμε απευθείας στο μπροστινό μέρος.

Ας ρίξουμε μια ματιά στο αποτέλεσμα:

Με αυτόν τον τρόπο, υλοποιούμε απλώς τη λειτουργία ενός websocket. Έχουμε λοιπόν ένα συγκεκριμένο μήνυμα και κλείνουμε το chat, πώς να το αντιμετωπίσουμε;

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

Ο κωδικός του μπροστινού μέρους δεν έχει αλλάξει, μόνο το back-end έχει τροποποιηθεί.

Στην πραγματικότητα, είναι πολύ απλό να εφαρμοστεί η επικοινωνία websocket εδώ.

Φυσικά μπορούμε να το χρησιμοποιήσουμε και σε αιτήματα

  • Εξαρτάται
  • Ασφάλεια
  • Κουλουράκι
  • Επί κεφαλής
  • Μονοπάτι
  • Ερώτηση

Μπορούμε να δούμε το ακόλουθο παράδειγμα μιας απλής γραφής backend

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

Αν και έχουμε απλώς εφαρμόσει το backend, μπορούμε να δούμε ότι το fastapi έχει καλή υποστήριξη για το websocket