状态 #

Nakama 用户可以在连接时设置状态消息,并在在线时进行更新。

用户可以彼此关注,从而获得状态变化通知。知道好友在线,在做什么,太好了。

状态为每一连接而设置,用户断开连接时被擦除。如果用户从多个设备连接,则允许每个设备具有不同的状态。

设置状态 #

默认情况下,用户首次连接时没有状态,而且不会对其关注者显示在线。为显示在线,用户必须设置状态。

状态可以很简单,比如用户发给其关注者的文字消息,也可以是包含复杂信息的结构化 JSON 字符串,例如用户当前所在的实时多人游戏比赛 ID – 这样他们的好友就可以加入他们!

Client
1
socket.updateStatus("Hello everyone!");
Client
1
await socket.UpdateStatusAsync("Hello everyone!");
Client
1
rtClient->updateStatus("Hello everyone!");
Client
1
socket.updateStatus("Hello everyone!").get();
Client
1
2
3
4
5
var update : NakamaAsyncResult = yield(socket.update_status_async(JSON.print({"status": "happy"})), "completed")
if update.is_exception():
    print("An error occurred: %s" % update)
    return
print("Status updated")
Client
1
socket.status_update(socket, "Hello everyone!")

Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

通过此操作,可以随时设置和更新此状态。

显示离线 #

如用户需要显示离线或“不可见”,他们可以擦除其状态,达到这个目的。如果用户断开连接,其关注者将接收到与此相同的状态更新。

Client
1
socket.updateStatus();
Client
1
await socket.UpdateStatusAsync(null);
Client
1
rtClient->updateStatus("");
Client
1
socket.updateStatus(null).get();
Client
1
2
3
4
5
var leave : NakamaAsyncResult = yield(socket.update_status_async(""), "completed")
if leave.is_exception():
    print("An error occurred: %s" % leave)
    return
print("Status updated")

Code snippet for this language Defold has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

接收状态更新 #

在用户更新其状态时,其所有关注者都将接收到一个事件,其中包含旧的和新的状态。客户端注册一个事件处理程序,会在收到状态更新事件时调用它。

Client
1
2
3
4
5
6
7
8
socket.onstatuspresence = (statuspresence) => {
    statuspresence.leaves.forEach((leave) => {
        console.log("User %o no longer has status %o", leave.user_id, leave.status);
    });
    statuspresence.joins.forEach((join) => {
        console.log("User %o now has status %o", join.user_id, join.status);
    });
};
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
socket.ReceivedStatusPresence += presenceEvent =>
{
    Console.WriteLine(presenceEvent);
    foreach (var joined in presenceEvent.Joins)
    {
        Console.WriteLine("User id '{0}' status joined '{1}'", joined.UserId, joined.Status);
    }
    foreach (var left in presenceEvent.Leaves)
    {
        Console.WriteLine("User id '{0}' status left '{1}'", left.UserId, left.Status);
    }
};
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
rtListener->setStatusPresenceCallback([](const NStatusPresenceEvent& event)
{
    for (auto& presence : event.leaves)
    {
        std::cout << "User " << presence.username << " no longer has status " << presence.status << std::endl;
    }

    for (auto& presence : event.joins)
    {
        std::cout << "User " << presence.username << " now has status " << presence.status << std::endl;
    }
});
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
SocketListener listener = new AbstractSocketListener() {
    @Override
    public void onStatusPresence(final StatusPresenceEvent presence) {
        for (UserPresence userPresence : presence.getJoins()) {
            System.out.println("User ID: " + userPresence.getUserId() + " Username: " + userPresence.getUsername() + " Status: " + userPresence.getStatus());
        }

        for (UserPresence userPresence : presence.getLeaves()) {
            System.out.println("User ID: " + userPresence.getUserId() + " Username: " + userPresence.getUsername() + " Status: " + userPresence.getStatus());
        }
    }
};
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func _ready():
    # First, setup the socket as explained in the authentication section.
    socket.connect("received_status_presence", self, "_on_status_presence")

func _on_status_presence(p_presence : NakamaRTAPI.StatusPresenceEvent):
    print(p_presence)
    for j in p_presence.joins:
        print("%s joined with status: %s" % [j.user_id, j.status])
    for j in p_presence.leaves:
        print("%s left with status: %s" % [j.user_id, j.status])

Code snippet for this language Defold has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

如果用户断开连接或显示为离线,他们将退出其以前的状态,但不会有相应的新状态。

关注用户 #

用户只能接收他们关注的人的状态更新。用户可以关注他们感兴趣的任何人,但通常会关注一些好友来查看他们何时在线,他们在做什么。

关注一组用户后,该操作将立即返回当前在线并设置了可见状态的用户的状态。

对用户的关注仅在当前会话中有效。当用户断开连接时,他们会自动取消关注在连接时关注的任何人。

Client
1
2
3
4
var status = await socket.followUsers(["<user id>"]);
status.presences.forEach((presence) => {
  console.log("User %o has status %o", presence.user_id, presence.status);
});
Client
1
await socket.FollowUsersAsync(new[] { "<user id>" });
Client
1
2
3
4
5
6
7
8
9
auto successCallback = [](const NStatus& status)
{
    for (auto& presence : status.presences)
    {
        std::cout << "User " << presence.username << " has status " << presence.status << std::endl;
    }
};

rtClient->followUsers({ "<user id>" }, successCallback);
Client
1
socket.followUsers("<user id>").get();
Client
1
2
3
4
5
6
var user_ids = ["<user-id1>", "<user-id2>"]
var status : NakamaRTAPI.Status = yield(socket.follow_users_async(user_ids), "completed")
if status.is_exception():
    print("An error occurred: %s" % status)
    return
print(status)

Code snippet for this language Defold has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.

取消关注用户 #

取消关注一组用户后,此用户将立即停止接收这些用户的任何进一步状态更新。

Client
1
socket.unfollowUsers(["<user id>"]);
Client
1
await socket.UnfollowUsersAsync(new[] { "<user id>" });
Client
1
rtClient->unfollowUsers({ "<user id>" });
Client
1
socket.unfollowUsers("<user id>").get();
Client
1
2
3
4
5
6
var user_ids = ["<user-id1>", "<user-id2>"]
var status : NakamaAsyncResult = yield(socket.unfollow_users_async(user_ids), "completed")
if status.is_exception():
    print("An error occurred: %s" % status)
    return
print(status)