Custom RPC freezing client

Hi all!

I’m working on this custom RPC call I got from here, it worked very well until now.
This is the code:

local nk = require("nakama")

local function list_all(context, payload)
  local all_results = {}
  local next_cursor = nil
  local ghost = payload
  repeat
    local results, cursor = nk.storage_list(nil, ghost, 100, next_cursor)
    for _, result in ipairs(results) do
      table.insert(all_results, result)
    end
    next_cursor = cursor
  until (not next_cursor)
  nk.logger_info(tostring(results))
  nk.logger_info(tostring(all_results))
  return nk.json_encode(all_results)
end
nk.register_rpc(list_all, "list_ghost")

While I had more than 1 storage itens, this code was working as intended, it would retrive up to 100 itens to the client, now I’m tetsing with only 1 storage item (It’s there and I make sure to check it beforehand), I get no result, nothing at all and the client just freezes waiting for a response.

The logger data is as folows:

"msg":"nil","runtime":"lua","rpc_id":"list_ghost"

and

"msg":"table: 0xc000564e40","runtime":"lua","rpc_id":"list_ghost" #table value here changes each time, just as an example 0xc000a0e840 etc.

I’m very lost in lua code, but I don’t think that would have a problem to get a single item?

Hello @luiscesjr,

It seems odd to me that you’re passing the payload directly into the collection field of the storage_list function, is that what’s intended?

I could not reproduce an issue calling storage_list on a collection with a single object, what version of the server are you running?

Hi @sesposito !

It seems odd to me that you’re passing the payload directly into the collection field of the storage_list function, is that what’s intended?

Yes, the storage_list is game related dependant, so I decided to send it with the payload depending on whatever the user is doing in-game, is it a bad practice? I’m still learning this “network side” of programming.

I could not reproduce an issue calling storage_list on a collection with a single object, what version of the server are you running?

It’s quite strange really, I have to populate the storage with dummy objects (in the respective collection) so it won’t freeze the client. I’m running the server version 3.11.0+c820042d.

This is the client code:

func ghost_data(pista_ghost, pista_time):
	var payload = pista_ghost
	var response : NakamaAPI.ApiRpc = yield(NakamaGlobals.client.rpc_async(NakamaGlobals.session, "list_ghost", payload), "completed")
       #If I don't have "dummies" on the storage, it will never get past this line, 
       #The engine freezes on yielding forever here without a response.
	if response.is_exception():
		print(response)
	else:
		var rng = RandomNumberGenerator.new()
		rng.randomize()
		var arr = parse_json(response["payload"])
		var who2get = []
		var random_number = arr.size() - 1
		for i in 3:
			who2get.append(rng.randi_range(0 , random_number)) 
		while who2get[0] == who2get[1] or who2get[0] == who2get[2] or who2get[1] == who2get[2]:
			who2get.clear()
			for i in 3:
				who2get.append(rng.randi_range(0 , random_number))
		ghost_1.append(arr[who2get[0]]["user_id"])
		ghost_2.append(arr[who2get[1]]["user_id"])
		ghost_3.append(arr[who2get[2]]["user_id"])
		get_user_name(arr,who2get,pista_time, pista_ghost)
		loading += 1

I am really crude on lua, I have no clue whatsoever as how to catch an error on the server appart from trying to log it. I’m reading and trying to understand how error handling works.

Yes, the storage_list is game related dependant, so I decided to send it with the payload depending on whatever the user is doing in-game, is it a bad practice? I’m still learning this “network side” of programming.

You can use it like this, but I’d advise on adding some validation on the keys that you allow the client to send, otherwise it could try to read collections he shouldn’t, and would also prevent the client from sending bad data.

Are you on the latest release of Godot? This could be an SDK issue or a problem in your code, as I couldn’t replicate this behaviour server side with the code you provided. If not, please upgrade. I’d also maybe try to comment out the else block and run the code, just to see if it still blocks with a single object in the collection, perhaps there’s some mistake in the logic.

Hope this helps.

1 Like

You can use it like this, but I’d advise on adding some validation on the keys that you allow the client to send, otherwise it could try to read collections he shouldn’t, and would also prevent the client from sending bad data.

Thanks for the tip, I’ll make sure to look into this and work it out.

Are you on the latest release of Godot? This could be an SDK issue or a problem in your code, as I couldn’t replicate this behaviour server side with the code you provided. If not, please upgrade. I’d also maybe try to comment out the else block and run the code, just to see if it still blocks with a single object in the collection, perhaps there’s some mistake in the logic.

I’m using the latest 3.5 RC, not the stable 3.4.X nor the alpha 4. I’ll make sure to test the code on other releases and also without the else. But even without the else it should run, right? I mean, if there was an error, the exception would catch it, and even if not, I tried putting print lines after the yield, before the error catching and after the else, it won’t reach any. Simply gets stuck there.
When I have more data after testing I’ll come back! Thank you!