Skip to main content

LCP Protocol Internals

This page documents the internal protocol mechanics of the LiveContentProtocol (LCP). For the high-level overview, connector patterns, and creating new connectors, see LCP & RPC.

LiveContentWrapper​

LiveContentWrapper (in io-oidis-services) is the core protocol encoder/decoder. Every connector call ultimately delegates to one of its four static factory methods:

MethodPurposeUsed by
InvokeMethod()Remote method invocationBaseConnector.invoke() / asyncInvoke()
setProperty()Remote property setterDirect usage via LiveContentWrapper.setProperty()
getProperty()Remote property getterDirect usage via LiveContentWrapper.getProperty()
AddEventHandler()Subscribe to backend eventsEvent-driven connectors

Each factory method creates a LiveContentWrapper instance, builds the wire-format protocol, sends it via the transport client, and returns a chainable callback API.

The Wire Format (IWebServiceProtocol)​

Every LCP message — request or response — is wrapped in IWebServiceProtocol:

{
id: number, // Request ID for correlation
clientId: number, // Browser client identifier
type: string, // e.g. "LiveContentWrapper.InvokeMethod"
status: number, // HTTP-style status code (200 = success)
origin: string, // Request origin for CORS
token: string, // Auth session token
data: { // ILiveContentProtocol payload
name: string, // "Namespace.ClassName.MethodName"
args: any[], // Serialized arguments
returnValue: any // Response value (in responses)
},
format: string, // Encoding: "json" or "auto"
version: "1.1" // Protocol version
}

The type field follows the pattern "LiveContentWrapper.<operation>" where operation is InvokeMethod, setProperty, getProperty, AddEventHandler, or getEvent.

Response Deserialization​

When a response arrives, LiveContentWrapper.getReturnValue() automatically deserializes the return value:

  1. Base64 detection — If format is not JSON and the value matches a Base64 pattern, it is decoded first
  2. JSON objects/arrays — Strings starting with { or [ are parsed as JSON
  3. Numeric strings — Converted to number (integer or double)
  4. Boolean strings — "true" / "false" converted to boolean
  5. Void/null — RETURN_VOID marker or "null" string returns null
  6. Non-string values — Returned as-is (already deserialized by transport)

Error Propagation​

When the backend throws an exception, the response arrives with type = "WebServiceClientEventType.ON_ERROR" and the data field contains IWebServiceException:

{
message: string, // Error message (may be Base64-encoded)
file: string, // Source file
line: number, // Line number
col: number, // Column number
code: number, // Error code
stack: string, // Full stack trace
args?: any // Custom error context
}

The wrapper reconstructs a full Error object with the original stack trace, wraps it in ErrorEventArgs, and either calls the registered OnError() handler or fires a global error event.

Event Handler Polling​

For WebSocket transports, backend events are pushed to the client in real-time. For HTTP/AJAX transports (which cannot receive server push), LiveContentWrapper implements a polling mechanism:

  1. AddEventHandler() sends the initial subscription request
  2. If the transport is not WebSocket, a polling loop starts
  3. Every 500ms, a getEvent protocol message is sent to check for pending events
  4. Received events are dispatched to all registered handlers asynchronously
  5. Polling stops when the client connection closes

Callback Chain API​

The LiveContentWrapper instance returned from factory methods implements a chainable API:

LiveContentWrapper.InvokeMethod(config)
.DataFormatter(($data) => transform($data)) // Optional: transform raw response
.OnError(($error) => handleError($error)) // Optional: handle errors
.Then(($result) => useResult($result)); // Required: handle success

Each step is optional except Then(). If OnError() is not provided, errors propagate to the global EventsManager.


See also: LCP & RPC | Connectors Reference | Response API