Get realtime online users and running matches

Hi,

Im trying to implement a RPC function that getting current count of online users and running matches in lua.

Question 1:

I know that each user has a online field, but its not DB field so that i can’t do a query to count current online user. Is there any recommended way to get current session count by lua?

Question 2:

About match list query (https://heroiclabs.com/docs/gameplay-multiplayer-server-multiplayer/#match-listings), there is a sample:

local nk = require("nakama")

local limit = 10
local isauthoritative = true
local label = ""
local min_size = 0
local max_size = 4
local query = "+label.mode:freeforall label.level:>10"
local matches = nk.match_list(limit, isauthoritative, label, min_size, max_size, query)
for _, match in ipairs(matches) do
  nk.logger_info(("Match id %s"):format(match.match_id))
end

For "local query = “+label.mode:freeforall label.level:>10"”. Is it for “label” returned by #match_init or setupstate for #match_create? I tried many cases for label query and i can’t realize what are label.mode and label.level meaning. Could you help provide a real case for it?

@renhades ,
Answer 1 : Here’s one way that we use for our game.
We have created custom stream for that purpose and upon successful authentication, user’s join that stream, and then we count the presences on that stream to get online players count. Also note that, whenever user disconnects from server, it’s removed from the streams too by default.
You can read more about them here - https://heroiclabs.com/docs/advanced-streams/.

Here’s a sample(assuming you are using Lua) -

local nk = require("nakama")

local stream_model = {}

stream_model.streams = {
    online_stream_id = {
        mode = 1000
    }
}

function stream_model.close_stream(stream_id)
    log.log_norm("[stream_model/close_stream] : closing stream" .. nk.json_encode(stream_id))

    nk.stream_close(stream_id)
end

function stream_model.join_stream(user_id, session_id, stream_id, hidden, persistence)
    --nk.logger_info("[stream_model/join_stream] : User " .. user_id .. " is joining stream = " .. nk.json_encode(stream_id))

    nk.stream_user_join(user_id, session_id, stream_id, hidden, persistence)
end

function stream_model.leave_stream(user_id, session_id, stream_id)
    --nk.logger_info("[stream_model/leave_stream] : User " .. user_id .. " is leaving stream = " .. nk.json_encode(stream_id))

    nk.stream_user_leave(user_id, session_id, stream_id)
end

function stream_model.count_users_on_stream(stream_id)
    local count = nk.stream_count(stream_id)

    --nk.logger_info("[stream_model/count_users_on_stream] : counting users on stream ".. nk.json_encode(stream_id) ..". Count = " .. count)

    return count
end

And then you could do something like this with an RPC call - to add user to that stream

function join_online_users_stream(context, _)
    --nk.logger_info("[join_online_users_stream] : User is joining online users stream = " .. context.username)

    local hidden = true
    local persistence = false
    stream_model.join_stream(context.user_id, context.session_id, stream_model.streams.online_stream_id, hidden, persistence)
end

And use this to get count of online players -

function count_users_on_online_users_stream()
    local count = stream_model.count_users_on_stream(stream_model.streams.online_stream_id)

    --nk.logger_info("[count_users_on_online_users_stream] : Count of online users = " .. count)

    return count
end
4 Likes

Answer 2 : Yes, label refers to what is returned from the match_init call(return state, tickrate, match_label).
You can see discussion here and get an idea about how you can use them.

If that doesn’t clear something for you, go ahead and ask.

2 Likes

Thanks. It’s more clear. I have other questions.

For Answer 1:

Are some number occupied by Nakama built-in features?

Do I need to prevent some terms for “mode”?

Is there a event that triggered at session started in lua? I tried #register_req_after on #authenticatecustom but the context is not included session_id.

For Answer 2:

Is it possible to count all matches without limit and returned specific columns (Prevent too large object)?

Are some number occupied by Nakama built-in features?

Yes, there are some modes used by built-in streams in nakama like notification stream(mode 0).
You can find more here - https://heroiclabs.com/docs/advanced-streams/#built-in-streams

Is there a event that triggered at session started in lua? I tried #register_req_after on #authenticatecustom but the context is not included session_id.

We also needed something like that to get the session_id right after the successful authentication to join that player to stream on server side like in the after hook for Authentication, but at that moment it was not possible, so we make a RPC call to join the stream from client side after successful authentication.

Is it possible to count all matches without limit and returned specific columns (Prevent too large object)?

I haven’t tried calling match listing without specifying limit( don’t know what will happen if set to 0). We just set the limit to a very high value to include all matches.
And yes you can specify a query = "+label.mode:freeforall label.level:>10" to match your needs or otherwise list all matches and do some filtering the returned matches as you like.

From client side, we can get session object but can’t know whats the session_id after successful authentication. Do you have any advice about getting session_id during RPC call?

@renhades
You can get the session id inside the context passed with the rpc call -

function some_rpc_call(context, payload)
    print("user_id = ", context.user_id, " session_id = ", context.session_id)
end

And you’ll have to call the rpc from client side on socket object like this -

IApiRpc result = await socket.RpcAsync(
                    "some_rpc_call",
                    "some_json_payload"
                );
1 Like

Thanks a lot again!