# 通知

**URL:** https://heroiclabs.com/docs/zh/nakama/tutorials/unity/pirate-panic/notifications/
**Summary:** 学习如何为Pirate Panic教程游戏添加通知。

---


# 通知

通知可以方便地让玩家在游戏中了解感兴趣的事件。在本节中，我们将学习在特定操作触发警报和消息时，如何使用 Nakama [通知](../../../../concepts/notifications/)引擎向玩家发送它们。

应用程序内通知可以从服务器发送，然后由客户端接收并在游戏中显示。如果通知被标记为持久性，则即使收件人处于离线状态，服务器也可以接受通知。

请记住，应用程序内通知与手机上的推送通知不同。仅当玩家在游戏中时，这些通知才会显示。

## 发送通知

首先，让我们设置服务器端代码来触发通知发送。

可以将通知绑定到在特定事件之前或之后触发的 [Register 挂钩](../../../../server-framework/introduction/#hooks)。Nakama 对用于检测事件发生时间的逻辑进行处理。

例如，如果想在玩家添加第一个好友时奖励他们，有一个 `RegisterAfterAddFriends` 挂钩在添加好友后运行：

**quests.ts**

```typescript
let afterAddFriendsFn: nkruntime.AfterHookFunction<void, nkruntime.AddFriendsRequest> = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, data: void, request: nkruntime.AddFriendsRequest) {
    let subject = JSON.stringify("A new friend!");
    let content = { reward: 1000 };
    let code = 1;
    let senderId = null; // Server sent
    let persistent = true;

    nk.notificationSend(ctx.userId, subject, content, code, senderId, persistent);
}

...
initializer.registerAfterAddFriends(afterAddFriendsFn); // Don't forget to register the hook!
```

此处，函数 `notificationSend` 将在用户 `ctx.userId` 添加新好友时发送通知。此函数中：

- `Content` 是一个 JSON 对象，具有用于您想在通知中发送的任何数据的自定义键值对
- `code` 用于指定自定义通知类型，可以是大于 `0` 的所需的任何值。代码 `0` 和以下各项由[系统](../../../../concepts/notifications/#notification-codes)保留
- 如果通知由另外一个玩家发送，则 `senderId` 将是发送者的用户 ID。在本例中，消息由服务器生成，因此它应为 `null`
- 如果通知具有 `persistent = true`，则即使玩家离线，也将发送通知。玩家重新加入时，他们可以用 [ListNotificationsAsync](../../../../concepts/notifications/#list-notifications) 读取待处理通知的列表

## 接收通知

现在我们有了一个发送通知的系统，让我们设置客户端。

为此我们也将函数绑定到挂钩，这次为通知到达时的 `ReceivedNotification` 挂钩。然后我们用此函数处理从服务器发送的数据：

**NotificationPopup.cs**

```csharp
public void Init(GameConnection connection) {
    connection.Socket.ReceivedNotification += NotificationReceived;
}

private class Reward {
    public int reward = 0;
}

private void NotificationReceived(IApiNotification notification) {
    if (notification.Code == 1) {
        Reward reward = JsonUtility.FromJson<Reward>(notification.Content);
        _titleText.text = notification.Subject;
        _descriptionText.text = "Received reward: " + reward.reward;
        ...
    }
}
```

此处我们接收 `IApiNotification` 形式的通知，其中包含我们在服务器上输入 `notificationSend` 的所有数据。

由于 `content` 是 JSON 对象，我们需要将其打开为 C# 对象。我们知道，预期的格式为具有包含一个数值的单一键 `reward` 的对象，因此我们可以用此结构创建类 `Reward`，并使用 `JsonUtility.FromJson` 将 `Content` 转换为它。

然后我们设置 Text 对象 `_titleText` 和 `_descriptionText`，通过所需的主题和描述进行分配。