JSON parse error in RPC call

Hi,

I have this error in Firefox when trying to call an RPC function frome the JS client:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

The client code:
const response = await client.rpc(session, "create_match_rpc", {})

The RPC function:

type response struct {
	MatchID string   `json:"matchID"`
}

func createMatchRPC(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
	params := make(map[string]interface{})
	if err := json.Unmarshal([]byte(payload), &params); err != nil {
			return "", err
	}

	matchID, err := nk.MatchCreate(ctx, "MatchHandler", params)

	if err != nil {
			return "", err
	}

	r := response{matchID}
	rr, err := json.Marshal(r)
	logger.Printf("rr:")
	logger.Printf(string(rr))
	return string(rr), nil
}

In Chrome everything works fine, the response’s payload looks like this: {"matchID":"caf156d8-55c6-47fe-89c2-acbeb9c7c77d.nakama1"}

But in Firefox, when looking at firebug’s network tab, I can see that the response’s payload looks like this: H4sIAAAAAAAA/6pWKkiszMlPTFGyUqqOUcpNLEnO8HSJUbKKUUpLTDFPtDQ20DU0NzXVNTE2NtBNMjY10jUwsjC0SDYysTQwM9bLS8xOzE00jFGqVaoFBAAA//8kAbCZTAAAAA==

I’m using Nakama JS client version 2.0.1

I believe you need to wrap the result in nk.json_encode().

Here is what our client code looks like in lua (stripped of entry fees and other details).

You might want to re-check the go example module in the docs as well.


local function create_match(context, payload)
    local modulename = "match_handler"
    local setupstate = {initialstate = nk.json_decode(payload)}

    local matchid = nk.match_create(modulename, setupstate)

    return nk.json_encode({["match_id"] = matchid, ["setupstate"] = setupstate})
end
nk.register_rpc(create_match, "create_match_rpc")

Also make sure you grab the latest build of the Nakama JavaScript client directly from the dist folder here https://github.com/heroiclabs/nakama-js/tree/master/dist - it’s newer than the tagged 2.0.1 release and contains a lot of fixes and updates.

We’ll tag a new official version of the client very soon, with even more improvements included.

Hi, thanks for your answers

@GroovyAntoidDev The Go example in the doc is the following:

func CreateMatchRPC(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
    params := make(map[string]interface{})
    if err := json.Unmarshal([]byte(payload), params); err != nil {
        return "", err
    }

    modulename := "pingpong" // Name with which match handler was registered in InitModule, see example above.
    if matchId, err := nk.MatchCreate(ctx, modulename, params); err != nil {
        return "", err
    } else {
        return matchId, nil
    }
}

(source: https://heroiclabs.com/docs/gameplay-multiplayer-server-multiplayer/#manually )

As you can see, it returns the matchId, not a JSON formatted string.

In my code I use jsonResponse, err := json.Marshal(response) which is I believe the equivalent of local jsonResponse = nk.json_encode(response).

@zyro I’m already using the latest Nakama JS client, I redownloaded nakama-js.umd.js yesterday from this folder.

From what I’ve tested, it happens here: https://github.com/heroiclabs/nakama-js/blob/master/src/api.gen.ts#L572
But only in Firefox, because here the response body is not a JSON.

Circling back to this we haven’t had any luck reproducing this issue. It would really help if you can set up a single-page test case that uses the Nakama JavaScript client and we can just open the page to see the issue.

Hi, the following code should raise the JSON parse error (in Firefox only, it works fine in Chrome):

(note the rpc function “create_match_rpc” should exist in the server)

const Nakama = require("@heroiclabs/nakama-js");

async function start() {
  const client = new Nakama.Client(
    "defaultkey",
    "gameserverurl.com",
    7350,
    true
  );

  const session = await client.authenticateCustom({
    id: "123",
    create: true,
    username: "username"
  });
  console.info("Successfully authenticated:", session);

  const response = await client.rpc(session, "create_match_rpc", {});
  console.log("rpc response", response);
}

start().catch(err => {
  console.error(err);
  alert(err);
});

(I’m using Nakama 2.7 with Docker and Go)

It would be great if you can package this as a repo on GitHub with the Go plugin code as well as an index.html file (packaged together with a copy of the exact Nakama JS client you use) we can just open in browser. I think that would help to avoid any unintended differences that might be introduced as we try to reproduce on our own environment.

I understand, I’ll try to do this when I got the time.

Also I found that this happen only with client.rpc(...), it works fine with socket.send({ rpc: { ... } }).

For someone still having this issue. In the example used by @doguh

func CreateMatchRPC(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
    params := make(map[string]interface{})
    if err := json.Unmarshal([]byte(payload), params); err != nil {
        return "", err
    }

    modulename := "pingpong" // Name with which match handler was registered in InitModule, see example above.
    if matchId, err := nk.MatchCreate(ctx, modulename, params); err != nil {
        return "", err
    } else {
        return matchId, nil
    }
}

the RPC function only returns a string matchID. But many client libraries expect a valid JSON. For example the javascript library parses the payload with JSON.parse(response.payload). To fix this the RPC functions have to return a valid JSON. So a quick fix would be:

return "{\"matchId\": \""+matchId+"\"}", nil