发送推送消息

Cloud Code C# 模块允许您通过 WebSocket 将消息推送到客户端。本页将概述此功能,并介绍如何在 Cloud Code 模块和 Cloud Code SDK 中使用此功能。

注意:推送消息和推送通知在游戏中有不同的用途。推送消息定向投放到游戏中参与度较高的活跃玩家,而推送通知是当游戏处于非活动状态或在后台运行时推送到设备。

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

用例和优点

推送消息可以有多种用途,例如:

用途示例优点
将消息从服务器实时推送到客户端,并增强游戏的互动性。您可以告知玩家有关游戏活动、更新或异步多人游戏(例如,竞技卡牌游戏)的信息。实时交互
通过直接向客户端推送更新和通知,让用户及时了解游戏中的最新活动、变更或行动。您可以在有新数据可用时立即通知用户,这样您就无需手动刷新或检查更新。这种功能对于需要频繁更新的游戏(例如实时战略游戏)特别有用。用户体验
使用 WebSocket 推送消息,比传统的轮询技术效率更高。您的客户端可以等待服务器在有新数据可用时发送这些数据,而不是不断要求服务器提供新数据。这样可以减少不必要的网络流量,并可以降低延迟。提高网络使用效率
利用推送模型的可扩展性来支持拥有大量用户的游戏。您可以在 Cloud Code 中使用推送消息一次性向所有已连接的客户端发送更新,从而降低拥有大量玩家的多人游戏的运营成本和请求量。可扩展性和成本
使用事件驱动模型来自定义游戏对不同类型的消息的响应。您可以根据收到的消息的 MessageType 属性触发不同的游戏操作。可自定义
作为 Unity 生态系统的一部分,Cloud Code 可以与其他 Unity 服务无缝结合使用。您可以使用 Unity 的 Authentication 服务处理玩家身份验证,并在 Unity 游戏引擎中处理消息。无缝集成

创建模块

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

  • SendPlayerMessage:向已连接的特定玩家发送一条消息。
  • SendProjectMessage:向项目中所有已连接的玩家广播一条消息。

重要:SendProjectMessage 方法向项目中所有已连接的玩家发送一条消息。这可能会造成滥用的机会,例如向玩家滥发消息。为了防止这种情况,您可以创建访问控制策略来限制玩家对终端的访问。

注意:您可以使用触发器向整个项目广播消息。请参阅使用示例:祝玩家新年快乐

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 编辑器

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

要在 Unity 编辑器中使用 Cloud Code,必须先安装 Cloud Code SDK,并将 Unity Gaming Services(Unity 游戏服务)项目关联到 Unity 编辑器。

关联项目

Unity Gaming Services(Unity 游戏服务)项目与 Unity 编辑器关联。您可以在 Unity Cloud Dashboard 中找到您的 UGS Project ID。

  1. 在 Unity 编辑器中,选择 Edit(编辑)> Project Settings(项目设置)> Services(服务)

  2. 关联您的项目。
    如果项目没有 Unity Project ID:

    1. 选择 Create a Unity Project ID(创建 Unity Project ID)> Organizations(组织),然后从下拉选单中选择一个组织。
    2. 选择 Create project ID(创建 Project ID)


    如果已有 Unity Project ID:

    1. 选择 Use an existing Unity project ID(使用现有 Unity Project ID)
    2. 从下拉选单中选择组织和项目。
    3. 选择 Link project ID(关联 Project ID)

此时将显示您的 Unity Project ID,并将项目关联到 Unity 服务。此外,还可以使用 UnityEditor.CloudProjectSettings.projectId 参数在 Unity 编辑器脚本中访问您的 Project ID。

SDK 安装

安装适用于 Unity 编辑器的最新 Cloud Code 包:

  1. 在 Unity 编辑器中,打开 Window(窗口)> Package Manager(包管理器)
  2. 在 Package Manager(包管理器)中,选择 **Unity Registry(Unity 注册表)**列表视图。
  3. 搜索 com.unity.services.cloudcode 或在列表中找到 Cloud Code 包。
  4. 选择包,然后单击 Install(安装)

注意:您可以使用 Cloud Code SDK 版本 2.4.0+ 订阅消息。

注意:要熟悉 Unity Package Manager(包管理器)界面,请参阅 Package Manager(包管理器)窗口文档。

SDK 设置

开始使用 Cloud Code SDK:

  1. 确保通过 Cloud Code 服务后台页面启用该服务。
  2. 确保 Cloud Code SDK 和 Authentication SDK 均已安装。
  3. 在 Unity 编辑器中选择 Edit(编辑)> Project Settings(项目设置)> **Services(服务)**登录到您的云项目。
  4. 在 Unity 编辑器中创建新的 C# Monobehaviour 脚本。请参阅 Unity 手册中的创建和使用脚本
  5. 在脚本中,使用 await UnityServices.InitializeAsync() 初始化 Core SDK。
  6. 在脚本中,初始化 Authentication SDK。

注意:玩家必须拥有有效的玩家 ID 和访问令牌才能访问 Cloud Code 服务。在使用任何 Cloud Code API 之前,您必须使用 Authentication SDK 对玩家进行身份验证。为此,您可以使用以下代码片段进行匿名身份验证,或查看身份验证文档,了解更多详细信息和其他登录方法。

C#

await AuthenticationService.Instance.SignInAnonymouslyAsync();

订阅消息

您可以订阅特定玩家或整个项目的消息。您可以使用以下代码片段作为 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 Runtime 运行

您可以通过 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>"}});

注意:您可以创建访问控制策略,拒绝玩家调用 SendProjectMessage 模块函数向游戏中的所有其他玩家发送项目消息。

事件

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

  • 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"