Send push messages

Cloud Code C# modules allow you to push messages to clients over a WebSocket. This page provides an overview of this feature and instructions on how to use it in Cloud Code modules and the Cloud Code SDK.

Note: Push messages and push notifications serve different purposes in your game. Push messages target players who are actively engaged in game play, and push notifications reach devices when the game is either inactive or operating in the background.

To send push messages, you need to call a module endpoint. You can subscribe to push messages from the Unity Editor.

Use cases and benefits

You can use push messages for a variety of purposes, such as the following:

UseExampleBenefit
Push messages from the server to clients in real time and enhance interactivity for your games.You can notify players about game events, updates, or asynchronous multiplayer games (for example, competitive card games).Real-time interaction
Keep users up-to-date with the latest events, changes, or actions in the game by pushing updates and notifications directly to the client.You can notify your users as soon as new data is available so you don't need to manually refresh or check for updates. This can be especially useful for games that require frequent updates, such as real-time strategy games.User experience
Use WebSockets to push messages for more efficiency than traditional polling techniques.Your client can wait for the server to send new data when it becomes available instead of continuously asking the server for new data. This reduces unnecessary network traffic and can lead to lower latency.Efficient network usage
Use the scalability of the push model to support games with a large number of users.You can use push messages in Cloud Code to send updates to all connected clients at once, and reduce the operating cost and amount of requests for multiplayer games with a large number of players.Scalability and cost
Customize your game's response to different types of messages with the event-driven model.You can trigger different game actions based on the MessageType property of the messages you receive.Customizability
As part of the Unity ecosystem, use Cloud Code is seamlessly with other Unity services.You can handle player authentication with Unity's Authentication service, and process the messages within the Unity game engine.Seamless integration

Create a module

The following code example demonstrates the basic structure for a module that includes two methods:

  • SendPlayerMessage: sends a message to a specific connected player.
  • SendProjectMessage: broadcasts a message to all connected players in the project.

Important: The SendProjectMessage method sends a message to all connected players in the project. This can create an opening for abuse, such as spamming players with messages. To prevent this, you can create an Access Control policy to limit player access to the endpoint.

Note: You can broadcast a message to the whole project by using Triggers. Refer to Use case sample: Wish players a happy new year.

The Unity.Services.CloudCode.Apis package provides the PushClient instance, which is the interface that you use to send push messages.

C#

using Microsoft.Extensions.DependencyInjection;
using Unity.Services.CloudCode.Core;
using Unity.Services.CloudCode.Apis;

namespace PushExample
{
    public class PushExample
    {
        [CloudCodeFunction("SendPlayerMessage")]
        public async Task<string> SendPlayerMessage(IExecutionContext context, PushClient pushClient, string message, string messageType, string playerId)
        {
            var response = await pushClient.SendPlayerMessageAsync(context, message, messageType, playerId);
            return "Player message sent";
        }

        // Recommended to use access control to limit access to this endpoint
        [CloudCodeFunction("SendProjectMessage")]
        public async Task<string> SendProjectMessage(IExecutionContext context, PushClient pushClient, string message, string messageType)
        {
            var response = await pushClient.SendProjectMessageAsync(context, message, messageType);
            return "Project message sent";
        }
    }

    public class ModuleConfig : ICloudCodeSetup
    {
        public void Setup(ICloudCodeConfig config)
        {
            config.Dependencies.AddSingleton(PushClient.Create());
        }
    }
}

To learn how to deploy a module, refer to the Deploying Hello World page.

Set up the Unity Editor

The Cloud Code SDK provides an interface for subscribing to messages. You can subscribe to messages for a specific player or for the entire project.

To use Cloud Code in the Unity Editor, you must first install the Cloud Code SDK and link your Unity Gaming Services project to the Unity Editor.

Link your Unity Gaming Services project with the Unity Editor. You can find your UGS project ID in the Unity Cloud Dashboard.

  1. In Unity Editor, select Edit > Project Settings > Services.

  2. Link your project.
    If your project doesn't have a Unity project ID:

    1. Select Create a Unity Project ID > Organizations, then select an organization from the dropdown.
    2. Select Create project ID.


    If you have an existing Unity project ID:

    1. Select Use an existing Unity project ID.
    2. Select an organization and a project from the dropdowns.
    3. Select Link project ID.

This shows your Unity Project ID and links the project to Unity services. You can also access your project ID in a Unity Editor script with the UnityEditor.CloudProjectSettings.projectId parameter.

SDK installation

Install the latest Cloud Code package for Unity Editor:

  1. In the Unity Editor, open Window > Package Manager.
  2. In the Package Manager, select the Unity Registry list view.
  3. Search for com.unity.services.cloudcode, or locate the Cloud Code package in the list.
  4. Select the package, then click Install.

Note: You can subscribe to messages with Cloud Code SDK versions 2.4.0+.

Note: To familiarize yourself with the Unity Package Manager interface, refer to Package Manager window documentation.

SDK setup

Get started with the Cloud Code SDK:

  1. Ensure the service is enabled via the Cloud Code service dashboard page.
  2. Ensure that you have installed both the Cloud Code and the Authentication SDKs.
  3. Sign into your cloud project from within Unity Editor by selecting Edit > Project Settings > Services.
  4. Create a new C# Monobehaviour script in Unity Editor. Refer to Creating and using scripts in the Unity Manual.
  5. In the script, initialize the Core SDK using await UnityServices.InitializeAsync().
  6. In the script, initialize the Authentication SDK.

Note: Players must have a valid player ID and access token to access the Cloud Code services. You must authenticate players with the Authentication SDK before using any of the Cloud Code APIs. You can do this with the following code snippet for anonymous authentication or check the documentation for Authentication for more details and other sign-in methods.

C#

await AuthenticationService.Instance.SignInAnonymouslyAsync();

Subscribe to messages

You can subscribe to messages for a specific player or for the entire project. You can use the following code snippet as a guide for a MonoBehaviour script for your Unity project.

The script authenticates as an anonymous player, and subscribes to both player-specific and project-specific messages and handles various types of events:

C#

using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Unity.Services.Authentication;
using Unity.Services.CloudCode;
using Unity.Services.CloudCode.Subscriptions;
using Unity.Services.Core;
using UnityEngine;
namespace CloudCode
{
	public class CloudCodePushExample : MonoBehaviour
	{
    	async void Start()
        {
            await UnityServices.InitializeAsync();
            await AuthenticationService.Instance.SignInAnonymouslyAsync();
            Debug.Log(AuthenticationService.Instance.PlayerId);
            await SubscribeToPlayerMessages();
            await SubscribeToProjectMessages();
        }
        // This method creates a subscription to player messages and logs out the messages received,
        // the state changes of the connection, when the player is kicked and when an error occurs.
        Task SubscribeToPlayerMessages()
        {
            // Register callbacks, which are triggered when a player message is received
            var callbacks = new SubscriptionEventCallbacks();
            callbacks.MessageReceived += @event =>
            {
                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"));
                Debug.Log($"Got player subscription Message: {JsonConvert.SerializeObject(@event, Formatting.Indented)}");
            };
            callbacks.ConnectionStateChanged += @event =>
            {
                Debug.Log($"Got player subscription ConnectionStateChanged: {JsonConvert.SerializeObject(@event, Formatting.Indented)}");
            };
            callbacks.Kicked += () =>
            {
                Debug.Log($"Got player subscription Kicked");
            };
            callbacks.Error += @event =>
            {
                Debug.Log($"Got player subscription Error: {JsonConvert.SerializeObject(@event, Formatting.Indented)}");
            };
            return CloudCodeService.Instance.SubscribeToPlayerMessagesAsync(callbacks);
        }
        // This method creates a subscription to project messages and logs out the messages received,
        // the state changes of the connection, when the player is kicked and when an error occurs.
        Task SubscribeToProjectMessages()
        {
            var callbacks = new SubscriptionEventCallbacks();
            callbacks.MessageReceived += @event =>
            {
                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"));
                Debug.Log($"Got project subscription Message: {JsonConvert.SerializeObject(@event, Formatting.Indented)}");
            };
            callbacks.ConnectionStateChanged += @event =>
            {
                Debug.Log($"Got project subscription ConnectionStateChanged: {JsonConvert.SerializeObject(@event, Formatting.Indented)}");
            };
            callbacks.Kicked += () =>
            {
                Debug.Log($"Got project subscription Kicked");
            };
            callbacks.Error += @event =>
            {
                Debug.Log($"Got project subscription Error: {JsonConvert.SerializeObject(@event, Formatting.Indented)}");
            };
            return CloudCodeService.Instance.SubscribeToProjectMessagesAsync(callbacks);
        }
	}
}

Send messages to players

To send messages to players, call either the SendPlayerMessage or the SendProjectMessage function from your module.

To learn how to run modules, refer to Run modules.

Run from Unity runtime

You can send messages to other players via the CallModuleEndpointAsync method of the CloudCodeService instance. You need to use the module name and function name as its first two arguments, and a dictionary with the necessary parameters as the third argument.

For example, to send a player message, you can call:

var sendPlayerMessageResult = await CloudCodeService.Instance.CallModuleEndpointAsync<string>("PushExample", "SendPlayerMessage",
	new Dictionary<string, object> {{"message", "hello with a player message from PushExample!"}, {"messageType", "testType"}, {"playerId", "<other-unity-player-ID>"}});

Note: You can create an Access Control policy to deny players from calling the SendProjectMessage module function that sends a project message to all other players in your game.

Events

Both player-specific and project-specific subscriptions have four event handlers:

  • MessageReceived: triggers when the player receives a new message.
  • ConnectionStateChanged: triggers when the state of the connection changes.
  • Kicked: triggers when the server forcefully unsubscribes the player from messages. This doesn't close the WebSocket connection, nor does it prevent the game client from subscribing to messages again.
  • Error: triggers when an error occurs in handling the connection or when the player receives messages.

Message envelope

The IMessageReceivedEvent is an interface that represents a message the player receives from the push service. The event triggers when Cloud Code sends a message via a WebSocket connection.

Refer to the table below for the payload of theIMessageReceivedEvent interface:

PropertyDescriptionExample
SpecVersionThe specification version of the received message's envelope. Use this property to ensure the client can process the message correctly.1.0
IdA unique identifier for the message. Use this property to track or log messages.4f88f657-27da-4b1d-a013-9033dbc7b48b
SourceThe source of the message's envelope. This indicates where the message originated from, which you can use to debug or route messages. The source is always the domain of Cloud Code.https://cloud-code.service.api.unity.com
TypeThe message's envelope type. This property indicates the type of data the message contains and helps the client decide how to process it. The value is always a Cloud Code message type.com.unity.services.cloud-code.push.v1
TimeThe date and time of the message creation. You can use this property to log the messages, or to calculate latency.2023-09-19T10:26:40.436878688Z
ProjectIdThe ID of the project the message is associated with.b6670776-9fd3-4d66-8bf4-63fb1112dc95
EnvironmentIdThe ID of the environment that the message is for. You can use this property to differentiate between different environments such as development, staging, and production.a4bc2571-d1e7-4507-9cc9-80b687d48d8f
CorrelationIdAn identifier that you can use to track a sequence of related messages. For instance, if multiple messages form a conversation or workflow, they might share a correlation ID.afbd7c6e-e999-4ca2-86fc-3c908ba83bf2
MessageThe actual message content sent from Cloud Code to the player."hello world!"
MessageTypeThe type of the message that the player receives. This is similar to Type, but is specific to the content of the message rather than the envelope."Information"