Websocket (Pro)
High-performance WebSocket interface for bidirectional signal exchange (Pro)
This feature was added in realvirtual 6.3 (Professional).
This interface requires the REALVIRTUAL_JSON compiler define. See Newtonsoft JSON for setup instructions.
Overview
The WebSocket Realtime Interface provides high-performance, bidirectional signal exchange over WebSocket connections. It operates as both server and client, enabling connectivity between two Unity instances, external applications, PLCs, or any system that supports WebSocket communication.
Built on the FastInterface framework, it offers thread-safe background communication, automatic reconnection, change detection, and low-latency signal transport.
Key capabilities:
Server and Client mode in a single component
Flat JSON wire protocol (v2) for easy integration from any language
Signal import from remote side with automatic direction inversion
SSL/TLS support (wss://) for secure connections through reverse proxies
Pattern-based signal direction detection for external systems without PLC-style type prefixes
Subscribe filtering so clients only receive the signals they need
Setup
Adding the Interface
Drag the WebsocketRealtimeInterface prefab into your scene, or add the component to an existing GameObject
The interface appears as a child of your realvirtual root object
Create PLC signal objects (PLCInputBool, PLCOutputFloat, etc.) as children of the interface

Server Mode
Set Is Server to true (in the Connection Settings foldout). The server listens on the configured address and port and broadcasts signal data to all connected clients.
Address: IP to bind to (
127.0.0.1for localhost,0.0.0.0for all interfaces)Port: TCP port (default: 1234)
Client Mode
Set Is Server to false. The client connects to a remote WebSocket server.
Address: IP address of the server
Port: TCP port of the server
Use SSL: Enable for
wss://connections (e.g. through a reverse proxy)Path: Optional URL path (e.g.
/my-bridge/wsfor reverse proxy routing)Client Name: Identification sent during handshake
Signal Import
Client Mode Import (Edit Mode)
In client mode, you can import signals from the remote server without manually creating them:
Make sure the remote server is running
Click Import Signals in the Inspector (works in edit mode — no play mode required)
The interface connects, requests the signal catalog, creates local mirror signals with inverted directions, and disconnects
You can also use Test Connection to verify connectivity without importing.
Server Mode Import (Play Mode)
In server mode, you can import signals from connected clients during play mode:
Start the simulation so the server is running and clients are connected
Click Import Signals from Clients in the Inspector
The server broadcasts an import request to all connected clients and creates local mirror signals with inverted directions
This is useful for discovering which signals a remote client provides without manually defining them.
Properties
Configuration
Update Cycle Ms
Communication loop interval in milliseconds (default: 10)
Only Transmit Changed Inputs
Only send signals whose values changed since last cycle
Auto Reconnect
Automatically reconnect on connection loss
Reconnect Interval Seconds
Seconds between reconnection attempts
Max Reconnect Attempts
Maximum number of reconnection attempts before giving up (-1 = unlimited)
Debug Mode
Enable detailed logging for troubleshooting
Connection Settings
Is Server
true = WebSocket server, false = WebSocket client
Address
IP address to bind (server) or connect to (client)
Port
TCP port for communication (default: 1234)
Use SSL
(Client only) Use wss:// for encrypted connections
Path
(Client only) Optional URL path appended after host:port
Client Name
(Client only) Name sent during init handshake
Connect On Play
Automatically connect when entering play mode
Status
Connected Clients
(Server only) Number of currently connected clients
Signal Import
Default Signal Direction
Direction for imported signals when no pattern matches (Input or Output)
Use Pattern Matching
Enable name-based direction detection
Input Patterns
Name substrings that identify signals Unity writes (e.g. "Unity")
Output Patterns
Name substrings that identify signals the PLC writes
Use Cases
Unity-to-Unity distributed simulation with signal mirroring
External application integration (web dashboards, custom HMIs, test frameworks)
PLC bridge connections (e.g. via a bridge application running on ctrlX CORE or other edge devices)
WebGL builds where TCP-based protocols are not available
Wire Protocol v2 Reference
The WebSocket Realtime Interface uses a flat JSON protocol. All messages are UTF-8 encoded JSON objects sent as WebSocket text frames. There is no double-encoding - all fields are native JSON types.
Message Envelope
Every message has a type field that determines its purpose:
Message Types
init - Client Identification
init - Client IdentificationSent by the client immediately after the WebSocket connection is established.
type
string
Always "init"
version
int
Protocol version (2)
name
string
Client identification name
data - Cyclic Signal Exchange
data - Cyclic Signal ExchangeSent cyclically in both directions. Contains signal names and their current values.
type
string
Always "data"
signals
object
Map of signal name to current value. Values are native JSON types: true/false for bool, numbers for int/float, strings for text.
import_request - Signal Discovery Request
import_request - Signal Discovery RequestSent from one side to request the full signal catalog from the other side.
import_answer - Signal Catalog Response
import_answer - Signal Catalog ResponseResponse to import_request. Contains all signal names, their current values, and their PLC type strings.
signals
object
Signal name to current value
signalTypes
object
Signal name to type string. Recognized types: PLCInputBool, PLCOutputBool, PLCInputInt, PLCOutputInt, PLCInputFloat, PLCOutputFloat, PLCInputText, PLCOutputText. Neutral types without prefix (e.g. Bool, Float) are also accepted.
Direction inversion on import: When the receiving side imports signals, the direction is inverted:
Remote
PLCInputBool(remote reads from PLC) becomes localPLCOutputBool(local writes to Unity)Remote
PLCOutputBool(remote writes from PLC) becomes localPLCInputBool(local reads from Unity)
subscribe - Filter Server Output
subscribe - Filter Server OutputSent by the client to tell the server which signals it wants to receive. The server then only sends matching signals in data messages. If no subscribe message is sent, the server sends all signals.
snapshot - Immediate Full State
snapshot - Immediate Full StateSent by the server after receiving a subscribe message. Contains the current values of all subscribed signals.
config_get - Read Server Configuration
config_get - Read Server ConfigurationSent by the client to request the current configuration from the server (e.g. a bridge application).
config_answer - Configuration Response
config_answer - Configuration ResponseSent by the server in response to config_get. Contains the current configuration as a key-value map.
config
object
Application-specific key-value configuration map. The structure depends on the server implementation.
config_set - Write Server Configuration
config_set - Write Server ConfigurationSent by the client to update configuration values on the server. The server should persist and apply the new configuration.
config_result - Configuration Update Result
config_result - Configuration Update ResultSent by the server in response to config_set. Reports whether the configuration was applied successfully.
success
boolean
true if the configuration was applied, false on error
message
string
Human-readable result message
The config messages are optional and application-specific. They are used by the ctrlX bridge to remotely configure publish intervals, logging levels, and Data Layer browse paths. If you implement your own server, you can define any key-value structure for the config field or ignore these messages entirely.
Signal Value Types
PLCInputBool / PLCOutputBool
boolean
true, false
PLCInputInt / PLCOutputInt
integer
42, -1, 0
PLCInputFloat / PLCOutputFloat
number
3.14, 0.0, -100.5
PLCInputText / PLCOutputText
string
"Running", ""
Implementing the Other Side
This section describes how to build your own WebSocket application that communicates with the realvirtual WebSocket Realtime Interface. You can use any programming language that supports WebSocket connections.
Connection Sequence
When connecting to a realvirtual server:
When running your own server that realvirtual connects to as client:
Example: Python Client
A minimal Python client that connects to a realvirtual server, imports signals, and exchanges data:
Example: Python Server
A server that realvirtual connects to as a client. This is useful when your application is the "host" and realvirtual is a connected client:
Example: C# Client (.NET)
For .NET applications (e.g. a bridge application on a PLC or edge device):
Example: JavaScript / TypeScript (Browser or Node.js)
Direction Mapping Guide
When implementing the other side, understanding signal direction is critical:
signalTypes: {"Speed": "PLCOutputFloat"}
Local PLCInputFloat named "Speed"
Your app writes Speed, Unity reads it
signalTypes: {"Enable": "PLCInputBool"}
Local PLCOutputBool named "Enable"
Your app reads Enable, Unity writes it
signalTypes: {"Value": "Float"}
Direction from pattern matching or default
Neutral type - no direction prefix
Rule of thumb: If your application writes a value, declare it as PLCOutput. If your application reads a value from Unity, declare it as PLCInput. realvirtual inverts the direction on import.
Tips for Implementers
JSON only - All messages are JSON text frames. Binary frames are not used.
No heartbeat required - The cyclic
datamessages serve as implicit heartbeat. If you stop sending data, the connection remains open.Partial updates -
datamessages do not need to contain all signals. You can send only the signals that changed.Type coercion - realvirtual will attempt to convert JSON number types. Sending
1for a float signal or1.0for an int signal works.Signal names - Use consistent names between both sides. Names are case-sensitive and matched exactly.
SSL/TLS - For production deployments through reverse proxies (nginx, traefik), configure
useSSL=trueand set thepathto match your proxy route.
Troubleshooting
Interface does not connect:
Check that the server is running and reachable on the configured address and port
For client mode, verify the address, port, SSL, and path settings
Use the Test Connection button to verify connectivity
Enable Debug Mode for detailed logging
Signals not updating:
Ensure signals are child GameObjects of the interface
Check signal directions (Input = Unity writes, Output = Unity reads)
Verify that signal names match exactly between both sides
Check the data messages being sent contain the expected signal names
Import creates wrong directions:
Review your
signalTypesin theimport_answer-PLCInputandPLCOutputare inverted on importFor neutral types, configure Input Patterns and Output Patterns or set the Default Signal Direction
See Also
Custom Interfaces (FastInterface) - How to build your own interfaces
Signal Manager - Managing PLC signals
Interfaces Overview - All available interfaces
Last updated