Pyjo.Transaction.WebSocket - WebSocket transaction

from Pyjo.Transaction.WebSocket import WebSocket

# Send and receive WebSocket messages
ws = WebSocket()
ws.send('Hello World!')
ws.on('message', lambda ws, msg: print(f'Message: {msg}'))
ws.on('finish', lambda ws, code, reason: print(f'WebSocket closed with status {code}.'))

# Or import the module, as in Google Python Style Guide

import Pyjo.Transaction.WebSocket

# Send and receive WebSocket messages
ws = Pyjo.Transaction.WebSocket.new()
ws.send('Hello World!')
ws.on('message', lambda ws, msg: print(f'Message: {msg}'))
ws.on('finish', lambda ws, code, reason: print(f'WebSocket closed with status {code}.'))

Pyjo.Transaction.WebSocket is a container for WebSocket transactions, based on RFC 6455 and RFC 7692.

Events

Pyjo.Transaction.WebSocket inherits all events from Pyjo.Transaction and can emit the following new ones.

binary

ws.on('binary', lambda ws, data: ...)

Emitted when a complete WebSocket binary message has been received.

ws.on('binary', lambda ws, data: print(f'Binary: {data}'))

drain

ws.on('drain', lambda ws: ...)

Emitted once all data has been sent.

ws.on('drain', lambda ws: ws.send(str(time.time())))

finish

ws.on('finish', lambda ws, code, reason: ...)

Emitted when the WebSocket connection has been closed.

frame

ws.on('frame', lambda ws, frame: ...)

Emitted when a WebSocket frame has been received.

@ws.on('frame')
def frame(ws, frame):
    print(f'FIN: {frame[0]}')
    print(f'RSV1: {frame[1]}')
    print(f'RSV2: {frame[2]}')
    print(f'RSV3: {frame[3]}')
    print(f'Opcode: {frame[4]}')
    print(f'Payload: {frame[5]}')

json

ws.on('json', lambda ws, json: ...)

Emitted when a complete WebSocket message has been received, all text and binary messages will be automatically JSON decoded. Note that this event only gets emitted when it has at least one subscriber.

ws.on('json', lambda ws, data: print(f'Message: {data["msg"]}'))

message

ws.on('message', lambda ws, msg: ...)

Emitted when a complete WebSocket message has been received, text messages will be automatically decoded. Note that this event only gets emitted when it has at least one subscriber.

ws.on('message', lambda ws, msg: print(f'Message: {msg}'))

resume

tx.on('resume', lambda tx: ...)

Emitted when transaction is resumed.

text

ws.on('text', lambda ws, data: ...)

Emitted when a complete WebSocket text message has been received.

ws.on('text', lambda ws, data: print(f'Text: {data}'))

See also

Pyjoyment, https://mojolicious.org.

Ported from Mojo::Transaction::WebSocket of Mojolicious 9.49.

class Pyjo.Transaction.WebSocket.Pyjo_Transaction_WebSocket(*, compressed: bool | None = None, established: bool | None = None, handshake: Pyjo_Transaction_HTTP | None = None, masked: bool | None = None, max_websocket_size: int | None = None, **kwargs: Any)[source]

Pyjo.Transaction.WebSocket inherits all methods from Pyjo.Transaction and implements the following new ones.

__init__(*, compressed: bool | None = None, established: bool | None = None, handshake: Pyjo_Transaction_HTTP | None = None, masked: bool | None = None, max_websocket_size: int | None = None, **kwargs: Any) → None[source]
ws = Pyjo.Transaction.WebSocket.new()
ws = Pyjo.Transaction.WebSocket.new(compressed=True)

Construct a new Pyjo.Transaction.WebSocket object.

build_message(frame: str | Mapping[str, Any]) → Frame[source]
frame = ws.build_message({'binary': data})
frame = ws.build_message({'text': data})
frame = ws.build_message({'json': {'test': [1, 2, 3]}})
frame = ws.build_message(chars)

Build WebSocket message.

client_read(chunk: bytes) → None[source]
ws.client_read(data)

Read data client-side, used to implement user agents such as Pyjo.UserAgent.

client_write() → bytes[source]
data = ws.client_write()

Write data client-side, used to implement user agents such as Pyjo.UserAgent.

closed() → Self[source]
ws = ws.closed()

Same as Pyjo.Transaction.Pyjo_Transaction.completed(), but also indicates that all transaction data has been sent.

compressed
boolean = ws.compressed
ws.compressed = boolean

Compress messages with permessage-deflate extension.

property connection: str | None[source]
id = ws.connection

Connection identifier.

established
boolean = ws.established
ws.established = boolean

WebSocket connection established.

finish(code: int | None = None, reason: str | None = None) → Self[source]
ws = ws.finish()
ws = ws.finish(1000)
ws = ws.finish(1003, 'Cannot accept data!')

Close WebSocket connection gracefully.

handshake
handshake = ws.handshake
ws.handshake = Pyjo.Transaction.HTTP.new()

The original handshake transaction, usually a Pyjo.Transaction.HTTP object.

property is_websocket: bool[source]
boolean = ws.is_websocket

True, this is a Pyjo.Transaction.WebSocket object.

property kept_alive: bool | None[source]
boolean = ws.kept_alive

Connection has been kept alive.

property local_address: str | None[source]
address = ws.local_address

Local interface address.

property local_port: int | None[source]
port = ws.local_port

Local interface port.

masked
boolean = ws.masked
ws.masked = boolean

Mask outgoing frames with XOR cipher and a random 32-bit key.

property max_websocket_size: int[source]
size = ws.max_websocket_size
ws.max_websocket_size = 1024

Maximum WebSocket message size in bytes, defaults to the value of the PYJO_MAX_WEBSOCKET_SIZE environment variable or 262144 (256KiB).

parse_message(frame: Sequence[Any]) → Pyjo_Transaction_WebSocket[source]
ws.parse_message((fin, rsv1, rsv2, rsv3, op, payload))

Parse WebSocket message.

property protocol: str | None[source]
proto = ws.protocol

Return negotiated subprotocol or None.

property remote_address: str | None[source]
address = ws.remote_address

Remote interface address.

property remote_port: int | None[source]
port = ws.remote_port

Remote interface port.

property req: Pyjo_Message_Request[source]
req = ws.req

Handshake request, usually a Pyjo.Message.Request object.

property res: Pyjo_Message_Response[source]
res = ws.res

Handshake response, usually a Pyjo.Message.Response object.

resume() → Self[source]
ws = ws.resume()

Resume handshake transaction.

send(msg: str | Mapping[str, Any] | Sequence[Any], cb: Callable[[...], Pyjo_Transaction_WebSocket] | None = None) → Self[source]
ws = ws.send({'binary': data})
ws = ws.send({'text': data})
ws = ws.send({'json': {'test': [1, 2, 3]}})
ws = ws.send((fin, rsv1, rsv2, rsv3, op, payload))
ws = ws.send(chars)
ws = ws.send(chars, lambda ws: ...)

Send message or frame non-blocking via WebSocket, the optional drain callback will be executed once all data has been written.

# Send "Ping" frame
from Pyjo.WebSocket import WS_PING
ws.send((1, 0, 0, 0, WS_PING, b'Hello World!'))
server_read(chunk: bytes) → None[source]
ws.server_read(data)

Read data server-side, used to implement web servers such as Pyjo.Server.Daemon.

server_write() → bytes[source]
data = ws.server_write()

Write data server-side, used to implement web servers such as Pyjo.Server.Daemon.

with_compression() → None[source]
ws.with_compression()

Negotiate permessage-deflate extension for this WebSocket connection.

with_protocols(*protos: str) → str | None[source]
proto = ws.with_protocols('v2.proto', 'v1.proto')

Negotiate subprotocol for this WebSocket connection.