Currently tested against and targeting Unity 6000.3.10f1 (Unity 6).
- Unity: Unity3D project with Core SignalR Plugin and example scene. For use in the editor and WebGL.
- Server: ASP.NET Core 10 project with SignalR hub/methods for connection that serves built Unity WebGL files.
make help # Show all available commands
make install-signalr # Install SignalR DLLs for Unity
make server # Run the server
make health # Check if server is runningThe Asset Package needed for adding the Plugin to a project can be found in the Releases.
To work with SignalR in the Unity Editor, package dependencies (targeting .NET Standard 2.0) are required.
See SETUP.md for detailed cross-platform installation instructions, or run the quick setup below:
# Requires PowerShell 7+ and .NET SDK
cd Unity/Assets/Plugins/SignalR/lib
pwsh ./signalr.ps1The WebGL build requires the SignalR JavaScript client. This is handled by a custom WebGL template (Assets/WebGLTemplates/SignalR/) that includes the <script> tag automatically.
To configure: Player Settings > Resolution and Presentation > Web Template — select SignalR
All WebGL builds (including player-mode tests) will include the SignalR client automatically.
Note: The JS client version (npm:
10.0.0) and .NET DLL version (NuGet:10.0.1insignalr.ps1) are versioned independently. Update the template'sindex.htmlwhen upgrading the JS client.
All plugin types are in the UnityWebGLSignalR namespace:
using UnityWebGLSignalR;- Init(string url): Initialize a new instance of HubConnectionBuilder with the URL
- Init(string url, SignalROptions options): Initialize with URL and configuration options (auth, transport, timeouts)
- Connect: Start the connection to the hub and bind events
- On: Bind to the callback of a named client handler
- Invoke(string methodName, params object[] args): Send arguments to a named hub method (WebGL: 0-10 args)
- Stop: Stop the connection to the hub
- Dispose: Clean up the connection and resources
- IsConnected: Returns
truewhen connected to the hub
- ConnectionStarted: Called on successful connection to the hub
- ConnectionClosed: Called when the hub connection is closed
As per the official SignalR API, up to 8 args can be received (On) and up to 10 args can be sent (Invoke).
- The example handler and hub method are set to serialize/deserialize a single argument as JSON.
Use SignalROptions to configure authentication, transport, and connection behavior:
| Option | Type | Description | Platforms |
|---|---|---|---|
AccessToken |
string |
Static Bearer auth token | Both |
AccessTokenFactory |
Func<Task<string>> |
Async token provider | Editor only |
Headers |
Dictionary<string,string> |
Custom HTTP headers | Both |
WithCredentials |
bool? |
Send cookies cross-origin (default: true) | Both |
Transport |
TransportType? |
Force WebSockets/SSE/LongPolling | Both |
SkipNegotiation |
bool? |
Skip negotiation (WebSockets only) | Both |
HttpTimeout |
int? |
HTTP request timeout in ms (default: 100000) | WebGL |
ServerTimeout |
int? |
Server activity timeout in ms (default: 30000) | Both |
KeepAliveInterval |
int? |
Ping interval in ms (default: 15000) | Both |
LogMessageContent |
bool? |
Log message bodies (default: false) | WebGL |
LogLevel |
SignalRLogLevel? |
Client log level | WebGL |
RetryDelays |
int[] |
Custom reconnect retry delays in ms | Both |
using UnityWebGLSignalR;
void Start()
{
var signalR = new SignalR();
signalR.Init("<SignalRHubURL>");
// Handler callback
signalR.On("<HandlerName>", (string payload) =>
{
var json = JsonUtility.FromJson<JsonPayload>(payload);
Debug.Log($"<HandlerName>: {json.message}");
});
// Connection callback
signalR.ConnectionStarted += (object sender, ConnectionEventArgs e) =>
{
Debug.Log($"Connected: {e.ConnectionId}");
var json = new JsonPayload { message = "<MessageToSend>" };
signalR.Invoke("<HubMethod>", JsonUtility.ToJson(json));
};
signalR.ConnectionClosed += (object sender, ConnectionEventArgs e) =>
{
Debug.Log($"Disconnected: {e.ConnectionId}");
};
signalR.Connect();
}
[Serializable]
public class JsonPayload
{
public string message;
}using UnityWebGLSignalR;
void Start()
{
var signalR = new SignalR();
signalR.Init("<SignalRHubURL>", new SignalROptions
{
AccessToken = "<YourJWTToken>",
Transport = TransportType.WebSockets,
SkipNegotiation = true
});
signalR.Connect();
}Run from the Unity Test Runner window (Window > General > Test Runner):
- EditMode tests: Options serialization, plugin construction, enum validation (no server required)
- PlayMode tests: End-to-end integration tests (requires
make serverrunning on localhost:5000)
Headless browser test (Playwright) that loads the built WebGL app and verifies the SignalR jslib bridge works end-to-end — connection, hub method invocation, and handler callbacks.
To run locally (requires a WebGL build in Server/wwwroot/):
make server & # Start the server
cd e2e && npm ci && npx playwright install chromium --with-deps
npx playwright test # Run smoke testTwo GitHub Actions workflows are included:
- Unity CI (
ci.yml) — Runs on PRs. EditMode tests → WebGL build → Playwright smoke test. - Release (
release.yml) — Runs on push tomain. Auto-determines version, builds WebGL + exports.unitypackagein parallel, commits fresh wwwroot, tags, and creates GitHub Release.
The Release workflow also supports workflow_dispatch with two optional inputs:
version: Override auto-detection with an explicit version (e.g.,1.0.0).dry-run: Run the full pipeline without committing or creating a release.
Releases are fully automated on merge to main:
- Major/minor version: Add a
version:X.Y.Zlabel to the PR before merging. - Patch version: No label needed — auto-increments the patch from the latest tag (e.g.,
1.0.0→1.0.1). - Manual release: Trigger the Release workflow via
workflow_dispatchwith an explicit version.
The release pipeline will: determine version → build WebGL + export .unitypackage (parallel) → commit wwwroot → create git tag → create GitHub Release with changelog and package attached.