发送推送消息

云代码 C# 模块允许您通过 WebSocket 将消息推送到客户端。本页提供了此功能的概述以及在云代码模块和云代码 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.

要发送推送消息,您需要调用模块端点。您可以从 Unity 编辑器订阅推送消息。

用例和优势

您可以将推送消息用于各种目的,例如以下目的

用途示例优势
从服务器实时推送到客户端,增强游戏交互性。您可以通知玩家有关游戏事件、更新或异步多人游戏(例如,竞技纸牌游戏)的信息。实时互动
通过将更新和通知直接推送到客户端,让用户了解游戏中最新事件、更改或操作。您可以通知您的用户何时有新数据可用,这样您就不需要手动刷新或检查更新。这对于需要频繁更新的游戏(例如实时策略游戏)尤其有用。用户体验
使用 WebSockets 推送消息,比传统的轮询技术更高效。您的客户端可以等待服务器在数据可用时发送新数据,而不是不断地向服务器请求新数据。这减少了不必要的网络流量,并可以降低延迟。高效的网络使用
使用推送模型的可扩展性来支持大量用户的游戏。您可以使用云代码中的推送消息同时将更新发送到所有连接的客户端,并减少具有大量玩家的多人游戏的运营成本和请求数量。可扩展性和成本
使用事件驱动模型定制游戏对不同类型消息的响应。您可以根据接收到的消息的 MessageType 属性触发不同的游戏操作。可定制性
作为 Unity 生态系统的一部分,使用云代码与其他 Unity 服务无缝集成。您可以使用 Unity 的身份验证服务处理玩家身份验证,并在 Unity 游戏引擎中处理消息。无缝集成

创建模块

以下代码示例演示了包含两种方法的模块的基本结构

  • SendPlayerMessage:将消息发送到特定连接的玩家。
  • SendProjectMessage:将消息广播到项目中所有连接的玩家。

重要提示:SendProjectMessage 方法会将消息发送到项目中所有连接的玩家。这可能会造成滥用漏洞,例如向玩家发送垃圾邮件。为了防止这种情况,您可以创建 访问控制 策略来限制玩家对端点的访问。

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

Unity.Services.CloudCode.Apis 包提供 PushClient 实例,它是用于发送推送消息的接口。

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());
        }
    }
}

要了解如何部署模块,请参阅 部署“Hello World” 页面。

设置 Unity 编辑器

云代码 SDK 提供了一个用于订阅消息的接口。您可以订阅特定玩家或整个项目的 消息。

要在 Unity 编辑器中使用云代码,您必须先安装云代码 SDK 并将您的 Unity 游戏服务项目 链接到 Unity 编辑器。

将您的 Unity 游戏服务项目 与 Unity 编辑器链接。您可以在 Unity 云控制台中找到您的 UGS 项目 ID。

  1. 在 Unity 编辑器中,选择 编辑 > 项目设置 > 服务

  2. 链接您的项目。
    如果您的项目没有 Unity 项目 ID

    1. 选择 创建 Unity 项目 ID > 组织,然后从下拉菜单中选择一个组织。
    2. 选择 创建项目 ID


    如果您有现有的 Unity 项目 ID

    1. 选择 使用现有的 Unity 项目 ID
    2. 从下拉菜单中选择一个组织和一个项目。
    3. 选择 链接项目 ID

这将显示您的 Unity 项目 ID 并将项目链接到 Unity 服务。您也可以使用 UnityEditor.CloudProjectSettings.projectId 参数在 Unity 编辑器脚本中访问您的项目 ID。

SDK 安装

为 Unity 编辑器安装最新的云代码包

  1. 在 Unity 编辑器中,打开 窗口 > 包管理器
  2. 在包管理器中,选择 Unity 注册表 列表视图。
  3. 搜索 com.unity.services.cloudcode,或在列表中找到云代码包。
  4. 选择该包,然后单击 安装

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 设置

开始使用云代码 SDK

  1. 确保通过云代码服务仪表板页面启用该服务。
  2. 确保您已安装云代码和身份验证 SDK。
  3. 通过选择 编辑 > 项目设置 > 服务,从 Unity 编辑器内登录您的云项目。
  4. 在 Unity 编辑器中创建一个新的 C# Monobehaviour 脚本。 请参考 Unity 手册中的 创建和使用脚本
  5. 在脚本中,使用 await UnityServices.InitializeAsync() 初始化 Core SDK。
  6. 在脚本中,初始化身份验证 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();

订阅消息

您可以订阅特定玩家或整个项目的 messages。 您可以使用以下代码段作为 Unity 项目的 MonoBehaviour 脚本指南。

该脚本将以匿名玩家身份进行身份验证,并订阅特定玩家和项目级别的消息,并处理各种类型的事件

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);
        }
	}
}

向玩家发送消息

要向玩家发送消息,请从您的模块调用 SendPlayerMessageSendProjectMessage 函数。

要了解如何运行模块,请参考 运行模块

从 Unity 运行时运行

您可以通过 CloudCodeService 实例的 CallModuleEndpointAsync 方法向其他玩家发送消息。 您需要使用模块名称和函数名称作为其前两个参数,并使用包含必要参数的字典作为第三个参数。

例如,要发送玩家消息,您可以调用

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.

事件

特定玩家和项目级别的订阅都有四个事件处理程序

  • MessageReceived:当玩家收到新消息时触发。
  • ConnectionStateChanged:当连接状态发生变化时触发。
  • Kicked:当服务器强制取消玩家的订阅消息时触发。 这不会关闭 WebSocket 连接,也不会阻止游戏客户端再次订阅消息。
  • Error:当处理连接时发生错误或玩家收到消息时触发。

消息信封

IMessageReceivedEvent 是一个接口,表示玩家从推送服务接收的消息。 当 Cloud Code 通过 WebSocket 连接发送消息时,将触发该事件。

有关 IMessageReceivedEvent 接口的有效载荷,请参考下表

属性描述示例
SpecVersion接收到的消息信封的规范版本。 使用此属性可确保客户端能够正确处理消息。1.0
Id消息的唯一标识符。 使用此属性跟踪或记录消息。4f88f657-27da-4b1d-a013-9033dbc7b48b
Source消息信封的来源。 这表示消息的来源,您可以使用它来调试或路由消息。 来源始终是 Cloud Code 的域。https://cloud-code.service.api.unity.com
Type消息的信封类型。 此属性表示消息包含的数据类型,并帮助客户端决定如何处理它。 该值始终是 Cloud Code 消息类型。com.unity.services.cloud-code.push.v1
Time消息创建的日期和时间。 您可以使用此属性记录消息,或计算延迟。2023-09-19T10:26:40.436878688Z
ProjectId与消息关联的项目的 ID。b6670776-9fd3-4d66-8bf4-63fb1112dc95
EnvironmentId消息所属环境的 ID。 您可以使用此属性区分不同的环境,例如开发、登台和生产。a4bc2571-d1e7-4507-9cc9-80b687d48d8f
CorrelationId您可以使用它来跟踪一系列相关消息的标识符。 例如,如果多条消息构成对话或工作流,它们可能共享一个相关性 ID。afbd7c6e-e999-4ca2-86fc-3c908ba83bf2
Message从 Cloud Code 发送到玩家的实际消息内容。"hello world!"
MessageType玩家接收的消息的类型。 这类似于 Type,但它是特定于消息内容而不是信封的。"Information"