Login & Session #

After connecting to a gateway with a Pragma token, the engine establishes a user session, such as player or operator.

The recommended configuration is to maintain a long-lived WebSocket. This enables bidirectional communication and platform notifications that can be sent to clients without polling patterns. This improves scalability and enables rich features such as party update broadcasts while minimizing network traffic.

Clients can also send messages through HTTP, which is useful for testing and web portal functionality. While fully featured, the HTTP flow is not designed for high-load production scenarios.

Gateways #

Player - Game clients connect to the Player gateway. This is facilitated by the Pragma SDK embedded in your game project.

Partner - This is a trusted endpoint protected by VPN. This enables server-to-server communication for trusted services such as dedicated game servers.

Operator - This is a trusted endpoint protected by VPN. This powers APIs for the web portal and other admin capabilities.

Quick Guides #

Making an HTTP request #

The pragmaGameToken or pragmaSocialToken JWT you receive in the authenticateOrCreate response must be included in the authorization header of every HTTP request you make to the platform depending on which service you are hitting.

curl --location --request POST 'http://127.0.0.1:10000/v1/rpc' \
--header 'Authorization: Bearer $pragmaGameToken' \
--header 'Content-Type: application/json' \
--data-raw '{
  "requestId": 1,
  "type": "InventoryRpc.GetInventoryV2Request",
  "payload": {
  }
}'

Connecting via Websocket #

The SDKs handle this connection step. pragmaSessionToken and SessionAuthToken are the JWTs for the social and game backends, and two WebSocket connections are established.

Unity
public void Connect(string pragmaSessionToken)
{
  if (Status > ConnectionStatus.NotConnected)
  {
    return;
  }

  if (_apiUrl.IsEmpty())
  {
    db.Error(LogTag, "Connect -- Must called Init to set api url before connecting.");
    SetStatus(ConnectionStatus.NotConnected);
    return;
  }
  _pragmaSessionToken = pragmaSessionToken;

  SetStatus(ConnectionStatus.Connecting);
  ConnectInternal();
}
Unreal
void FPragmaWebSocket::Connect(const FString& SessionAuthToken)
{
  if (ApiUrl.IsEmpty())
  {
    PRAGMA_LOG(Error, "FPragmaWebSocket::Connect -- Must called Init to set ApiUrl before connecting.");
    DisconnectedEvent.Broadcast(*this);
    return;
  }
  static const FString SubProtocol; // Intentionally empty. We're not using the websocket sub-protocol feature.
  const FString BearerHeader = FString::Printf(TEXT("Bearer %s"), *SessionAuthToken);
  const TMap<FString, FString> UpgradeHeaders = {
    {TEXT("Authorization"), BearerHeader},
    {TEXT("Accept"), TEXT("application/json")}
  };
  WebSocket = CreateWebSocket.IsBound()
    ? CreateWebSocket.Execute()
    : FWebSocketsModule::Get().CreateWebSocket(ApiUrl, SubProtocol, UpgradeHeaders);
  if (!ensure(WebSocket.IsValid()))
  {
    PRAGMA_LOG(Error, "FPragmaWebSocket::Connect -- Failed to create WebSocket.");
    DisconnectedEvent.Broadcast(*this);
    return;
  }
  WebSocket->OnConnected().AddSP(this, &FPragmaWebSocket::HandleWebSocketConnected);
  WebSocket->OnConnectionError().AddSP(this, &FPragmaWebSocket::HandleWebSocketConnectionError);
  WebSocket->OnClosed().AddSP(this, &FPragmaWebSocket::HandleWebSocketClosed);
  WebSocket->OnMessage().AddSP(this, &FPragmaWebSocket::HandleWebSocketTextMessage);
  WebSocket->OnRawMessage().AddSP(this, &FPragmaWebSocket::HandleWebSocketBinaryMessage);
  WebSocket->Connect();
}