The Core API uses a listener-based pattern (WSListener) and a non-async data path for maximum efficiency. Instead of receiving full messages, the user handles WSFrame objects. This allows for zero-copy data handling but requires the user to manage frame concatenation if a message spans multiple frames.
Key components:
WSListener: A class you subclass to implement event handlers like on_ws_connected and on_ws_frame.WSTransport: The object used to interact with the connection (e.g., transport.send(), transport.disconnect()).WSFrame: Represents a single WebSocket frame, providing access to the payload and parser state.WSMsgType: Enum for message types (e.g., TEXT, CLOSE).WSUpgradeRequest: Used in servers to facilitate routing via a listener factory.
# Core Client Example
import asyncio
from picows import ws_connect, WSFrame, WSTransport, WSListener, WSMsgType, WSCloseCode
class ClientListener(WSListener):
def on_ws_connected(self, transport: WSTransport):
transport.send(WSMsgType.TEXT, b"Hello world")
def on_ws_frame(self, transport: WSTransport, frame: WSFrame):
print(f"Echo reply: {frame.get_payload_as_ascii_text()}")
transport.send_close(WSCloseCode.OK)
transport.disconnect()
async def main():
transport, client = await ws_connect(ClientListener, "ws://127.0.0.1:9001")
await transport.wait_disconnected()
if __name__ == "__main__":
asyncio.run(main())
# Core Server Example
import asyncio
from picows import ws_create_server, WSFrame, WSTransport, WSListener, WSMsgType, WSUpgradeRequest
class ServerClientListener(WSListener):
def on_ws_connected(self, transport: WSTransport):
print("New client connected")
def on_ws_frame(self, transport: WSTransport, frame: WSFrame):
if frame.msg_type == WSMsgType.CLOSE:
transport.send_close(frame.get_close_code(), frame.get_close_message())
transport.disconnect()
else:
transport.send(frame.msg_type, frame.get_payload_as_memoryview())
async def main():
def listener_factory(r: WSUpgradeRequest):
# Routing can be implemented here by analyzing request content
return ServerClientListener()
server: asyncio.Server = await ws_create_server(listener_factory, "127.0.0.1", 9001)
for s in server.sockets:
print(f"Server started on {s.getsockname()}")
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())