asyncapi: '2.6.0' id: 'urn:com:photonengine:realtime:websocket' info: title: Photon Realtime Transport Protocol over WebSocket version: '1.0.0' description: | AsyncAPI 2.6 description of Photon's **WebSocket transport** for the Photon Realtime binary protocol. Photon Realtime (and everything built on it - PUN, Fusion, Quantum, Voice, Chat) is **not** a JSON API. It is a proprietary binary message protocol - operation requests, operation responses, and events, framed inside eNet-style commands (documented at https://doc.photonengine.com/realtime/current/reference/binary-protocol) - that can be carried over three transports: UDP (default, reliable and unreliable channels), TCP, and **WebSocket**. WebSocket is explicitly documented as a first-class transport, not a workaround: clients set `ConnectionProtocol` to `WebSocket` or `WebSocketSecure`, and per https://doc.photonengine.com/realtime/current/connection-and-authentication/secure-networks "Configure your client to use the protocol WebSocketSecure and set the port to 443 for it... Make sure the port is 80 for ws or 443 for wss." Self-hosted Photon Server's WebSocket listener defaults to port 9090 (Master) / 9091 (GameServer secure) per https://doc.photonengine.com/server/v4/operations/websockets-ssl-setup; Photon Cloud uses port 19090 for the equivalent Master listener. WebSocket is the primary transport used by WebGL and other browser-hosted game clients, which cannot open raw UDP/TCP sockets. IMPORTANT HONESTY NOTE: unlike Groq's SSE stream or a typical JSON WebSocket API, the *payload* carried over this WebSocket connection is Photon's own binary wire format, not JSON text frames. This document models the **connection life cycle and message envelope** (operation request / operation response / event, with their code + parameter structure) as officially described in Photon's binary protocol reference; it does not - and cannot - fully reproduce the byte-level encoding here. Treat the `payload` schemas below as a structural description of the binary envelope, not a literal JSON schema of the wire bytes. contact: name: API Evangelist email: kin@apievangelist.com url: https://apievangelist.com license: name: API documentation - Photon Engine Terms of Service url: https://www.photonengine.com/en-us/photon/terms-of-service x-transport-notes: transport: WebSocket (ws:// unsecured, wss:// secured) protocol: ws / wss direction: bidirectional mediaType: application/octet-stream (Photon binary protocol, not JSON text frames) alternativeTransports: - UDP (default; reliable and unreliable channels) - TCP connectionSequence: 'Name Server (region list + auth) -> Master Server (matchmaking/lobby) -> Game Server (room gameplay)' isJson: false source: https://doc.photonengine.com/realtime/current/connection-and-authentication/secure-networks defaultContentType: application/octet-stream servers: nameServer: url: ns.exitgames.com:{port} protocol: wss protocolVersion: '13' description: | Photon Cloud Name Server, reachable over WebSocketSecure. The Name Server returns the region list and hands the client off to a regional Master Server, which in turn hands the client off to a Game Server for actual room gameplay. Self-hosted deployments configure their own WebSocket listener (default port 9090 Master / 9091 GameServer secure); Photon Cloud's equivalent Master listener is port 19090. variables: port: default: '443' description: 443 for wss (WebSocketSecure); 80 for plain ws. enum: - '443' - '80' bindings: ws: method: GET bindingVersion: '0.1.0' channels: /photon/ws: description: | Single duplex WebSocket connection used for the entire Photon session against whichever server role (Name Server, Master Server, or Game Server) the client currently addresses. There is no per-message-type URL path in the real protocol; this channel represents the one long-lived socket carrying every operation request, operation response, and event for the connection's lifetime. bindings: ws: method: GET bindingVersion: '0.1.0' publish: operationId: sendOperationRequest summary: Client sends an Operation Request (e.g. Connect, JoinLobby, JoinRoom, CreateRoom, RaiseEvent, SetProperties). description: | The client sends a binary Operation Request: an 8-byte operation header carrying an operation code (uint8) plus a serialized hashtable of parameters (parameter code -> value), as described at https://doc.photonengine.com/realtime/current/reference/binary-protocol. Common operations include Authenticate, JoinLobby, JoinRandomRoom, CreateGame, JoinGame, Leave, RaiseEvent, and SetProperties. message: $ref: '#/components/messages/OperationRequest' subscribe: operationId: receiveOperationResponseOrEvent summary: Server sends an Operation Response or an Event. description: | The server replies to each Operation Request with an Operation Response carrying the same operation code plus a return code and optional debug string, and independently pushes Events (for example RaiseEvent broadcasts from other actors, or Join/Leave notifications) identified by an event code and a data hashtable. message: oneOf: - $ref: '#/components/messages/OperationResponse' - $ref: '#/components/messages/EventData' components: messages: OperationRequest: name: OperationRequest title: Operation Request (binary) summary: Client-to-server request identified by an operation code. contentType: application/octet-stream description: | Binary envelope: 8-byte operation header (operation code + parameter count) followed by a serialized parameter hashtable (parameter code -> typed value). Structurally summarized in JSON below for readability; the wire format is Photon's own binary serialization, not JSON. payload: $ref: '#/components/schemas/OperationEnvelope' examples: - name: joinRandomRoom summary: Structural summary of a JoinRandomRoom operation request. payload: operationCode: 226 operationName: JoinRandomRoom parameters: expectedMaxPlayers: 4 matchmakingMode: 0 OperationResponse: name: OperationResponse title: Operation Response (binary) summary: Server-to-client reply to a specific operation code. contentType: application/octet-stream description: | Binary envelope carrying the same operation code as the triggering request, a return code (0 = OK), an optional debug string, and a parameter hashtable of result values. payload: $ref: '#/components/schemas/OperationResponseEnvelope' examples: - name: joinRandomRoomOk summary: Structural summary of a successful JoinRandomRoom response. payload: operationCode: 226 operationName: JoinRandomRoom returnCode: 0 debugMessage: null parameters: roomName: room-af31c actorNr: 2 EventData: name: EventData title: Event (binary) summary: Server-pushed event identified by an event code. contentType: application/octet-stream description: | Binary envelope carrying an event code (uint8) and a parameter/data hashtable, pushed by the server without a corresponding client request - for example, custom gameplay events raised via RaiseEvent, or built-in Join/Leave/PropertiesChanged notifications. payload: $ref: '#/components/schemas/EventEnvelope' examples: - name: playerJoinedEvent summary: Structural summary of a built-in "actor joined" event. payload: eventCode: 254 eventName: Join data: actorNr: 3 actorProperties: nickName: player3 schemas: OperationEnvelope: type: object description: Structural summary of a binary Operation Request. Not a literal wire schema. required: - operationCode properties: operationCode: type: integer description: uint8 operation code identifying the requested action. operationName: type: string description: Human-readable operation name (e.g. JoinRandomRoom, RaiseEvent, SetProperties). parameters: type: object additionalProperties: true description: Serialized hashtable of parameter code -> typed value. OperationResponseEnvelope: type: object description: Structural summary of a binary Operation Response. Not a literal wire schema. required: - operationCode - returnCode properties: operationCode: type: integer operationName: type: string returnCode: type: integer description: 0 indicates success; non-zero values are operation-specific error codes. debugMessage: type: string nullable: true parameters: type: object additionalProperties: true EventEnvelope: type: object description: Structural summary of a binary Event. Not a literal wire schema. required: - eventCode properties: eventCode: type: integer description: uint8 event code identifying the event type. eventName: type: string description: Human-readable event name where a built-in code applies (e.g. Join, Leave, PropertiesChanged). data: type: object additionalProperties: true description: Serialized hashtable of event data.