websockets.server ================= .. py:module:: websockets.server Attributes ---------- .. autoapisummary:: websockets.server.CONNECTIONS websockets.server.TOKEN websockets.server.NOTFOUND websockets.server.SESSIONS websockets.server.STAFF_CONNECTIONS websockets.server.STAFF websockets.server.ACTIVE_CHATS websockets.server.CHANNELS Classes ------- .. autoapisummary:: websockets.server.WebSocketServer Functions --------- .. autoapisummary:: websockets.server.get_payload websockets.server.error websockets.server.acknowledge websockets.server.handle_listen websockets.server.handle_authentication websockets.server.handle_status websockets.server.handle_broadcast websockets.server.handle_manage websockets.server.handle_customer_chat websockets.server.handle_staff_chat websockets.server.handle_start websockets.server.process_request websockets.server.main Module Contents --------------- .. py:data:: CONNECTIONS :type: dict[str, set[websockets.asyncio.server.ServerConnection]] .. py:data:: TOKEN :value: '' .. py:data:: NOTFOUND .. py:data:: SESSIONS :type: dict[str, sqlalchemy.orm.Session] .. py:data:: STAFF_CONNECTIONS :type: dict[str, set[websockets.asyncio.server.ServerConnection]] .. py:data:: STAFF :type: dict[str, dict[str, onegov.user.User]] .. py:data:: ACTIVE_CHATS :type: dict[str, dict[uuid.UUID, onegov.chat.models.Chat]] .. py:data:: CHANNELS :type: dict[str, dict[str, set[websockets.asyncio.server.ServerConnection]]] .. py:class:: WebSocketServer(config: onegov.server.config.Config, session_manager: onegov.core.orm.SessionManager, host: str, *args: Any, **kwargs: Any) Bases: :py:obj:`websockets.asyncio.server.ServerConnection` A websocket server connection. This protocol handles multiple websocket applications: - Ticket notifications - Ticker - Chat Chat behaves differently from the others and will eventually be carved out into a separate service. To not interfere with any existing functionality, we try to refrain from making backwards-incompatible changes. That way, ticker and notifications should continue to work without any modification. TODO: Move chat to a dedicated service. .. py:attribute:: schema :type: str .. py:attribute:: user_id :type: str | None .. py:attribute:: signed_session_id :type: str | None .. py:attribute:: config .. py:attribute:: session_manager .. py:attribute:: host .. py:method:: populate_staff() -> None Populate staff users. .. py:method:: get_chat(id: uuid.UUID) -> onegov.chat.models.Chat :async: .. py:method:: update_database() -> None :async: .. py:property:: identity_secret :type: str The identity secret, guaranteed to only be valid for the current application id. .. py:method:: unsign(text: str, salt: str = 'generic-signer') -> str | None Unsigns a signed text, returning None if unsuccessful. .. py:property:: session :type: sqlalchemy.orm.Session .. py:property:: session_cache :type: onegov.core.cache.RedisCacheRegion A cache that is kept for a long-ish time. .. py:property:: namespace :type: str .. py:property:: application_id :type: str .. py:property:: application_config :type: dict[str, Any] .. py:property:: browser_session :type: onegov.core.browser_session.BrowserSession | dict[str, Any] .. py:function:: get_payload(message: str | bytes, expected: collections.abc.Collection[str]) -> onegov.core.types.JSONObject | None Deserialize JSON payload and check type. .. py:function:: error(websocket: websockets.asyncio.server.ServerConnection, message: str, close: bool = True) -> None :async: Sends an error. .. py:function:: acknowledge(websocket: websockets.asyncio.server.ServerConnection) -> None :async: Sends an acknowledge. .. py:function:: handle_listen(websocket: websockets.asyncio.server.ServerConnection, payload: onegov.core.types.JSONObject_ro) -> None :async: Handles listening clients. .. py:function:: handle_authentication(websocket: websockets.asyncio.server.ServerConnection, payload: onegov.core.types.JSONObject_ro) -> None :async: Handles authentication. .. py:function:: handle_status(websocket: websockets.asyncio.server.ServerConnection, payload: onegov.core.types.JSONObject_ro) -> None :async: Handles status requests. .. py:function:: handle_broadcast(websocket: websockets.asyncio.server.ServerConnection, payload: onegov.core.types.JSONObject_ro) -> None :async: Handles broadcasts. .. py:function:: handle_manage(websocket: websockets.asyncio.server.ServerConnection, authentication_payload: onegov.core.types.JSONObject_ro) -> None :async: Handles managing clients. .. py:function:: handle_customer_chat(websocket: WebSocketServer, payload: onegov.core.types.JSONObject_ro) -> None :async: Starts a chat. Handles listening to messages on channel. .. py:function:: handle_staff_chat(websocket: WebSocketServer, payload: onegov.core.types.JSONObject_ro) -> None :async: Registers staff member and listens to messages. .. py:function:: handle_start(websocket: websockets.asyncio.server.ServerConnection) -> None :async: .. py:function:: process_request(self: websockets.asyncio.server.ServerConnection, request: websockets.Request) -> websockets.Response | None Intercept initial HTTP request. Before establishing a WebSocket connection, a client sends a HTTP request to "upgrade" the connection to a WebSocket connection. Chat ---- We authenticate the user before creating the WebSocket connection. The user is identified based on the session cookie. In addition to the cookie, we require a one-time token that the user must have obtained prior to requesting the WebSocket connection. .. py:function:: main(host: str, port: int, token: str, config: onegov.server.config.Config | None = None) -> None :async: