Overview
SocketGate connects Unreal Engine 4.27 and 5.8 games to Amazon API Gateway WebSocket APIs (wss://<api-id>.execute-api.<region>.amazonaws.com/<stage>). It is useful for chat, lobbies, live events, notifications, turn-based play and anything else your backend pushes to players. The socket uses the engine's own WebSocket client; AWS signing and the management API use the bundled AWS SDK for C++. Every event arrives on the game thread.
- Socket Connection object: On Connected, On Message, On Closed, On Error, On Reconnecting; Send Text, Send Json Action, Close.
- $connect authorization: None, IAM (a presigned SigV4 URL from Cognito identity pool credentials) or Token (header or query parameter for a Lambda authorizer), plus extra headers and query parameters.
- Auto-reconnect with exponential back-off and jitter. Every attempt signs a fresh URL, because presigned URLs expire.
- Keep-alive: API Gateway closes connections after 10 minutes without traffic, so SocketGate sends a message whenever the client has been quiet.
- Send And Wait For Reply: request/response over the socket, matched by a generated requestId.
- Post To Connection, Get Connection, Delete Connection for dedicated servers and tools.
Requirements
| Requirement | Details |
|---|---|
| Unreal Engine | 4.27 and 5.8 |
| Platforms | Win64, Linux and Android |
| Modules | SocketGate (Runtime), SocketGateSdk (prebuilt AWS SDK for C++ 1.11.916 in Source/ThirdParty) |
| Dependencies | No other plugins. Uses the engine's WebSockets module. On Linux and Android the SDK uses the engine's libcurl, OpenSSL and certificate store. |
| AWS | An AWS account with an API Gateway WebSocket API. API Gateway, Lambda and Cognito usage is billed by AWS. |
Installation
- Install SocketGate from Fab into your engine, or copy the
SocketGatefolder into your project'sPluginsfolder. - Enable SocketGate in Edit > Plugins and restart the editor.
- Open Project Settings > Plugins > SocketGate and set Default WebSocket Url and Auth Mode. For IAM mode also set Region and Identity Pool Id.
- C++ only: add
PublicDependencyModuleNames.Add("SocketGate");to yourBuild.cs.
Setting up AWS
1. The WebSocket API
- In the API Gateway console create a WebSocket API with the route selection expression
$request.body.action. - Add the routes
$connect,$disconnect,$defaultand your own routes (for examplesendmessage), usually with Lambda integrations. - Add a
pingroute with a Mock integration for the keep-alive message{"action":"ping"}, or let$defaulthandle it. - Deploy to a stage (for example
production). The stage page shows the WebSocket URL; copy it into Default WebSocket Url.
2. Protect $connect with IAM (recommended for game clients)
In the console open Routes > $connect > Route request and set Authorization to AWS_IAM, then deploy the API again. With the AWS CLI:
aws apigatewayv2 get-routes --api-id abc123
aws apigatewayv2 update-route --api-id abc123 --route-id r1s2t3 --authorization-type AWS_IAM
aws apigatewayv2 create-deployment --api-id abc123 --stage-name production
On WebSocket APIs, authorization only applies to $connect. Once a client is connected it can use every route.
3. The Cognito identity pool role
Create an Amazon Cognito identity pool. Enable guest access if players may connect before signing in, and add your identity providers. Then allow the pool's IAM role (authenticated and/or guest) to open connections to your API and nothing else:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123/production/$connect"
}]
}
Replace the region, account id (123456789012), API id (abc123) and stage with your own. Use abc123/*/$connect to allow every stage.
4. The server role (connection management)
Code that pushes messages to clients (your Lambda functions, or a dedicated server using Post To Connection) needs execute-api:ManageConnections:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "execute-api:ManageConnections",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123/production/*/@connections/*"
}]
}
The * after the stage covers POST (Post To Connection), GET (Get Connection) and DELETE (Delete Connection). Never give this permission to the players' identity pool role.
DefaultGame.ini and in packaged games. Use them only for development and dedicated servers; players should always use the identity pool. Shipping builds refuse settings keys unless Allow Static Keys In Shipping is enabled.Quick start
- Call Create Socket Connection (leave Url empty to use the settings) and promote the result to a variable.
- From the variable, bind On Connected, On Message, On Closed and On Error, then call Connect.
- In On Connected call Send Json Action with Route
sendmessageand Payload Json{"text": "hi"}. This sends{"action":"sendmessage","text":"hi"}. - In On Message read the text, for example with Get JSON Field (Path
text) or JSON To Struct. - Call Close when the player leaves.
Connection object
USocketGateConnection is a Blueprint type. Its options are copied from the project settings when it is created; change them on the object before calling Connect.
| Member | Kind | Description |
|---|---|---|
| Connect | Callable | Opens the connection, signing the URL first in IAM mode. Returns false if the connection is already active or the URL is not ws:// / wss://. |
| Close | Callable | Closes the connection and stops reconnecting. Status Code is 1000 (normal) or 3000-4999; Reason is optional. On Closed fires when the server confirms, or after 5 seconds. |
| Send Text | Callable | Sends a text frame. Returns false when the connection is not open or the text is larger than API Gateway's 128 KB limit. |
| Send Json Action | Callable | Sends {"action": Route, ...fields of Payload Json}. Payload Json must be a JSON object or empty. The field name comes from Route Field. |
| Is Connected | Pure | True while the socket is open. |
| Get State | Pure | Not Connected, Connecting, Connected, Reconnecting or Closing. |
| On Connected | Event | The connection is open. Also fires after every successful reconnect. |
| On Message | Event | (Message) A text message arrived. Replies to Send And Wait For Reply arrive here too. |
| On Closed | Event | (Status Code, Reason, Was Clean) The connection closed or dropped. If Get State returns Reconnecting, the next attempt is already scheduled. |
| On Error | Event | (Error) A connection attempt failed (handshake, signing, token, timeout), or reconnecting gave up (ReconnectFailed). |
| On Reconnecting | Event | (Attempt, Delay Seconds) A reconnect attempt was scheduled. |
Options (read / write on the object)
Url, Auth Mode, Auth Token, Token Location, Token Header Name, Token Query Name, Headers, Query Parameters, Protocols, Signing Region, Presign Expiry Seconds, Connect Timeout Seconds, Auto Reconnect, Max Reconnect Attempts, Reconnect Base Delay Seconds, Reconnect Max Delay Seconds, Keep Alive Interval Seconds, Keep Alive Message, Route Field, Request Id Field. The Settings section explains each one.
$connect integration has to answer with the Sec-WebSocket-Protocol header, or the handshake fails.Authorization
| Auth Mode | API Gateway setup | What SocketGate sends |
|---|---|---|
| None | $connect with authorization NONE | The URL with your Query Parameters, plus your Headers. |
| IAM (SigV4) | $connect with authorization AWS_IAM | The URL presigned with AWS Signature Version 4 (service execute-api) using the plugin's credentials. Query Parameters are signed too. The signing region comes from the execute-api host name; set Signing Region for a custom domain. |
| Token | $connect with a Lambda REQUEST authorizer, identity source route.request.header.Authorization or route.request.querystring.token | Auth Token (or, if empty, the token last passed to Set Login Token) in the header Token Header Name or the query parameter Token Query Name. Your authorizer verifies it, for example a Cognito user pool ID token. |
Signing runs on a background worker, because credentials may need a network round trip. The socket itself is created and used on the game thread. URLs are presigned for Presign Expiry Seconds (default 300). Once a connection is open it no longer needs the URL; API Gateway keeps connections open for up to 2 hours.
Reconnect & keep-alive
- Auto Reconnect (default on) reacts to failed attempts and to connections the server or network dropped. It does not reconnect after you call Close, or after a normal close (1000) from the server, for example Delete Connection.
- The delay starts at Reconnect Base Delay Seconds (1 s) and doubles with every attempt up to Reconnect Max Delay Seconds (30 s), with plus or minus 20% jitter so clients do not reconnect all at once. A successful connection resets the count.
- After Max Reconnect Attempts failed attempts in a row (default 10, 0 = never give up) On Error fires with
ReconnectFailedand the state becomes Not Connected. - Every IAM attempt signs a new URL, so expired signatures and refreshed Cognito credentials are handled for you. API Gateway ends every connection after 2 hours; the reconnect brings it back.
- Keep-alive: when the client has sent nothing for Keep Alive Interval Seconds (default 300, 0 = off), it sends Keep Alive Message (default
{"action":"ping"}). API Gateway closes connections that are idle for 10 minutes. - The handshake times out after Socket Connect Timeout Seconds (default 15) and counts as a failed attempt.
Request / reply
Send And Wait For Reply (Connection, Route, Payload Json, Timeout Seconds, Request Id Field Name) sends {"action": Route, "requestId": "<32 hex digits>", ...}. It fires On Reply (Reply = the whole message) when a message with the same top-level requestId string arrives. Otherwise it fires On Timeout after the timeout (0 = Default Reply Timeout Seconds), or On Failure if the connection is not open or closes while waiting. You can stop waiting with Cancel.
Your backend only has to echo the id. In a Lambda integration (Node.js):
import { ApiGatewayManagementApiClient, PostToConnectionCommand } from "@aws-sdk/client-apigatewaymanagementapi";
export const handler = async (event) => {
const { domainName, stage, connectionId } = event.requestContext;
const body = JSON.parse(event.body);
const api = new ApiGatewayManagementApiClient({ endpoint: `https://${domainName}/${stage}` });
await api.send(new PostToConnectionCommand({
ConnectionId: connectionId,
Data: JSON.stringify({ requestId: body.requestId, score: 1200 })
}));
return { statusCode: 200 };
};
Another way: give the route a route response. API Gateway then sends the integration's response body straight back to the client.
Server side: connection management
Dedicated servers and tools with IAM credentials (Static Keys or the Default Credential Chain, with the server role above) can push to clients and manage them through the API Gateway management API. The connection id is $context.connectionId / event.requestContext.connectionId in your route integrations.
| Node | Inputs | Outputs | Description |
|---|---|---|---|
| Post To Connection | Connection Id, Data, Endpoint | On Success / On Failure (Info, Error) | Sends Data (up to 128 KB) to one client. Error.Code GoneException means the client is no longer connected. |
| Get Connection | Connection Id, Endpoint | On Success / On Failure (Info, Error) | Returns Connected At, Last Active At, Source Ip and User Agent. |
| Delete Connection | Connection Id, Endpoint | On Success / On Failure (Info, Error) | Disconnects a client. |
| Resolve Identity | Force Refresh | On Success / On Failure (Identity Id, Error) | Fetches the Cognito identity and credentials now, for example right after login, so problems show up before the first IAM connection. |
Endpoint is https://<api-id>.execute-api.<region>.amazonaws.com/<stage>. When it is empty, SocketGate uses Default Management Endpoint, and if that is empty too it uses Default WebSocket Url with wss:// changed to https://. The signing region comes from the host name.
Functions
| Node | Description |
|---|---|
| Create Socket Connection | Creates a connection with the options from the project settings. Url empty = Default WebSocket Url. |
| Make WebSocket Url | Builds wss://<api-id>.execute-api.<region>.amazonaws.com/<stage>. |
| Set Region | Switches the AWS region for every following request. |
| Set Credential Mode | Overrides the credential mode from the settings at runtime. |
| Set Login Token | Signs the player in to the identity pool with a provider token (Cognito user pool, Google, Apple, Facebook, OpenID). Token mode connections without their own Auth Token send this token. |
| Clear Login Tokens | Forgets all login tokens and the cached identity; the player becomes a guest. |
| Set Static Credentials | Uses the given keys from now on (Static Keys mode), for example temporary keys handed out by your backend. |
| Get Identity Id | The player's Cognito identity id; empty until credentials were resolved once. |
| Make User Pool Provider Name | Builds the login key of a Cognito user pool: cognito-idp.<region>.amazonaws.com/<pool id>. |
| Is Configured | Returns false and a reason when the credential settings are incomplete (needed for IAM mode and the management nodes). |
| Struct To JSON | Converts any struct to a JSON object string, for example a Payload Json. |
| JSON To Struct | Fills a struct from a JSON object string; missing fields keep their defaults. |
| Get JSON Field | Reads one value with a path such as player.stats[2].score. |
| Cancel | On a latent node's return value: none of its pins fire any more. |
| Is Finished | On a latent node's return value: true after it finished or was cancelled. |
Credentials
Credentials are only needed for IAM mode and for the management nodes. None and Token modes do not use AWS credentials at all.
| Mode | Use for | How |
|---|---|---|
| Cognito Identity Pool | Game clients | Guests get unauthenticated credentials; after Set Login Token the player gets the authenticated role. Credentials refresh automatically before they expire. |
| Static Keys | Development, dedicated servers, keys from your backend | Settings keys or Set Static Credentials (with an optional session token). |
| Default Credential Chain | Servers and tools | Environment variables, the ~/.aws profile, ECS and EC2 instance roles. |
C++ API
// Build.cs: PublicDependencyModuleNames.Add("SocketGate");
#include "SocketGateConnection.h"
#include "SocketGateLibrary.h"
// UPROPERTY() USocketGateConnection* Connection;
Connection = USocketGateLibrary::CreateSocketConnection(this, FString());
Connection->AuthMode = ESocketGateAuthMode::Iam;
Connection->OnConnected.AddDynamic(this, &AMyActor::HandleConnected); // UFUNCTION() void HandleConnected();
Connection->OnMessage.AddDynamic(this, &AMyActor::HandleMessage); // UFUNCTION() void HandleMessage(const FString& Message);
Connection->Connect();
void AMyActor::HandleConnected()
{
Connection->SendJsonAction(TEXT("sendmessage"), TEXT("{\"text\":\"hi\"}"));
}
The latent node classes (USocketGateReplyAction, USocketGateManageAction, USocketGateIdentityAction) can also be created from C++ through their static factory functions; bind the delegates, then call Activate().
Types
| Type | Kind | Members |
|---|---|---|
| USocketGateConnection | Object | See Connection object |
| FSocketGateError | Struct | Code, Message, Http Status, Retryable |
| FSocketGateConnectionInfo | Struct | Connection Id, Connected At, Last Active At, Source Ip, User Agent |
| ESocketGateAuthMode | Enum | None, IAM (SigV4), Token |
| ESocketGateTokenLocation | Enum | Header, Query Parameter |
| ESocketGateState | Enum | Not Connected, Connecting, Connected, Reconnecting, Closing |
| ESocketGateCredentialMode | Enum | Cognito Identity Pool, Static Keys, Default Credential Chain |
Settings
Project Settings > Plugins > SocketGate (saved to DefaultGame.ini). WebSocket, reconnect, keep-alive and reply options are copied into each connection when it is created.
| Setting | Default | Description |
|---|---|---|
| Region | us-east-1 | Region of your API and identity pool. URLs on execute-api.<region>.amazonaws.com sign with their own region. |
| Request Timeout Ms / Connect Timeout Ms | 30000 / 5000 | Time limits of AWS requests (credentials, management calls). |
| Max Retries | 3 | Automatic retries of AWS requests for throttling and transient errors. |
| Worker Threads | 2 | Background threads that sign URLs and run management calls. |
| Verify SSL / Log Sdk Warnings | On / On | TLS verification of AWS requests; SDK warnings in LogSocketGate. |
| Credential Mode | Cognito Identity Pool | Cognito Identity Pool, Static Keys or Default Credential Chain. |
| Identity Pool Id | (empty) | For example us-east-1:01234567-89ab-cdef-0123-456789abcdef. |
| Allow Guest Access | On | Unauthenticated identities before Set Login Token. The pool must allow guest access too. |
| Access Key Id / Secret Access Key | (empty) | Static Keys mode. Saved in DefaultGame.ini - development and servers only. |
| Allow Static Keys In Shipping | Off | Static keys from the settings are refused in Shipping builds unless enabled (dedicated servers). |
| Default WebSocket Url | (empty) | wss://<api-id>.execute-api.<region>.amazonaws.com/<stage>, used when Create Socket Connection gets no Url. |
| Auth Mode | IAM (SigV4) | None, IAM (SigV4) or Token. |
| Token Location / Token Header Name / Token Query Name | Header / Authorization / token | Where Token mode sends the token. |
| Presign Expiry Seconds | 300 | Lifetime of each presigned URL (10-3600). |
| Route Field | action | Field that carries the route in Send Json Action ($request.body.action). |
| Socket Connect Timeout Seconds | 15 | Time allowed for the WebSocket handshake. |
| Auto Reconnect | On | Reconnect after errors and dropped connections. |
| Max Reconnect Attempts | 10 | Failed attempts in a row before giving up; 0 = never give up. |
| Reconnect Base / Max Delay Seconds | 1 / 30 | Exponential back-off range (plus or minus 20% jitter). |
| Keep Alive Interval Seconds | 300 | Send Keep Alive Message after this long without sending; 0 = off. Keep it under 600. |
| Keep Alive Message | {"action":"ping"} | The keep-alive text. |
| Request Id Field | requestId | Field used by Send And Wait For Reply. |
| Default Reply Timeout Seconds | 10 | Used when Send And Wait For Reply has Timeout Seconds 0. |
| Default Management Endpoint | (empty) | https://<api-id>.execute-api.<region>.amazonaws.com/<stage> for the management nodes; empty = derived from Default WebSocket Url. |
Troubleshooting
| Error code | Cause and fix |
|---|---|
InvalidUrl | Url (or Default WebSocket Url) is empty or does not start with wss:// or ws://. |
ConnectFailed | The handshake failed. In IAM mode the usual cause is a 403: the role lacks execute-api:Invoke on .../<stage>/$connect, the API was not redeployed after switching $connect to AWS_IAM, the region is wrong (set Signing Region for custom domains), or the device clock is off. In Token mode the authorizer denied the token. Check the API's CloudWatch logs. |
ConnectTimeout | No answer within Socket Connect Timeout Seconds: network problem or wrong host. |
NoToken | Token mode without Auth Token and without Set Login Token. |
NotConfigured / NotAuthorizedException | IAM mode: set the Identity Pool Id, enable guest access on the pool, or call Set Login Token with a fresh token. |
ReconnectFailed | Max Reconnect Attempts failed attempts in a row. Call Connect again later. |
NotConnected / Timeout | Send And Wait For Reply: the connection was not open, or no message with the same requestId arrived. Make sure your backend copies requestId into its reply. |
GoneException | Post To Connection / Get Connection: the client has disconnected. Remove the connection id from your records. |
ForbiddenException / AccessDeniedException | Management calls: the server credentials lack execute-api:ManageConnections on .../<stage>/*/@connections/*. |
NoEndpoint | Management calls: set Endpoint on the node, Default Management Endpoint or Default WebSocket Url. |
Unavailable | The SDK library could not be loaded or the engine is shutting down. Check the Output Log for LogSocketGate errors. None and Token modes keep working without it. |
| Messages to a route never arrive | The message must be JSON with the route field ({"action":"sendmessage"}); unknown routes go to $default, or API Gateway answers with an error message if there is none. |
Credits
© 2026 Alpha XP — alphaxp.net · Support: support@alphaxp.net. Includes the AWS SDK for C++ and the AWS Common Runtime (Apache License 2.0). Built and verified warning-free for Unreal Engine 4.27 and 5.8.