Forum BigDB String value changing when passed from server to client

Discussion and help relating to Player.IO's database solution, BigDB.

String value changing when passed from server to client

Postby mgray417 » December 6th, 2011, 11:12 pm

So I tried posting about this before, but it got deleted for some reason so here I am giving it another shot. :|

I am storing usenames in BigDB for users that come from Kongregate. I am accessing the value stored in BigDB on the server side, and then passing that value, the username, as a string back to the client side. For some reason, the string value coming through on the client side isn't what is being passed by the server side. In fact its completely different.

I have tried checking the values coming through from BigDB on the server side, and they are in fact pulling the correct username string out of BigDB. Once I have that value I immediately pass it to the client so it can put it up on the screen for other users to see on the match screen that players view while waiting to start a game.

Here is my server side code:
Code: Select all
Message m2 = Message.Create("ChatInit");

foreach(Player p in this.Players)
{
                String checkName = p.ConnectUserId;
                String newName = "";

                if (checkName.StartsWith("simple"))
                {
                    p.isFromKongregate = false;
                   
                    PlayerIO.BigDB.Load("playerObjects", p.ConnectUserId, delegate(DatabaseObject result)
                    {
                        newName = result.GetString("username");
                        p.username = newName;
                    });
                }
                else
                {
                    p.isFromKongregate = true;
                    PlayerIO.BigDB.Load("kongPlayers", p.ConnectUserId, delegate(DatabaseObject result)
                    {
                        newName = result.GetString("kongUsername");
                        p.username = newName;
                    });                   
                }
               
                m2.Add(p.Id, newName);
}

player.Send(m2);



And here is the corresponding handler in the flash client side:
Code: Select all
connection.addMessageHandler("ChatInit", function(m:Message){
   for( var a:int=1;a<m.length;a+=2)
   {            
      matchScreen.addUser(m.getString(a),m.getString(a+1));
   }
})


The string value stored in BigDB that I am trying to access:
"mgray417"

The resulting string value coming back from the server that the client receives:
"kong5781093"

The "kong5781093" value happens to be the BigDB objects key, (as well as my kongregate userid, which is why i am using a separate DB for kongregate users), so I thought maybe that the server side is actually passing the object as opposed to the String value maybe, but that's just not the case.

So basically by the time the client receives the message from the server, it is a completely different string somehow.

I have tried tracing everything out in the client when it comes back, as well as adding an error log entry for the strings on the server before they are sent, still no idea how this is happening.

Any help would be GREATLY appreciated! Please don't delete this thread mods!

Thanks,
Mike
mgray417
 
Posts: 13
Joined: February 17th, 2010, 10:00 pm

Re: String value changing when passed from server to client

Postby Henrik » December 7th, 2011, 3:03 pm

I can see that you're not handling the asynchronous BigDB calls correctly, and that probably screws up the entire thing.

The code you put in the callback to BigDB.Load doesn't execute immediately, and the main thread doesn't wait for it. Instead, it happens sometime later maybe in a different thread. From the point of your main thread, what your code does is this:

Code: Select all
Message m2 = Message.Create("ChatInit");
foreach(Player p in this.Players)  {
    String newName = "";
    //Fire off a bigdb load that sets newName to something, later, asynchronously.
    m2.Add(p.Id, newName);
}
player.Send(m2);

This means that the first time in your loop, newName is probably still empty, and it will only have a value on the rare occasion that the callback manages to execute and set newName right between the two statements in the loop. The main thread won't wait for the callback to execute before adding newName to the message, and there's no guarantee in what order each callback executes. It might finish fetching the BigDB object for the second player before the first.

So the way to fix this specific piece of code is to add the id and username to the message inside the callback, and do the sending in the last callback that fires, not the callback of the last player in the collection.

However, if we step back a bit and look at what you're doing, we quickly realize that you'll do a ton of unnecessary BigDB loads. Every time a player joins your room, you'll do a single BigDB lookup for every player in the room, including the guy that just joined, and you have to wait for all of those to complete before you can send something out.

The way to improve that is to make each player load his own values only when he joins the room and put that in the username property you made on the Player object, and only access that for other players. Something like this:

Code: Select all
public override void UserJoined (Player player) {
    PlayerIO.BigDB.Load("playerObjects", player.ConnectUserId, delegate(DatabaseObject result) {
        //Store result from BigDB on object
        player.username = result.GetString("username");
        //Send message to player with all existing players
        Message m = Message.Create("ChatInit");
        foreach (Player p in Players) {
            m.Add(p.Id, p.username);
        }
        player.Send(m);
        //Send message to all other players that someone joined
        Broadcast("UserJoined", player.Id, player.username);
    });
}

Note that everything happens inside the callback because we don't have the results from the BigDB load elsewhere, and that we only do one BigDB load per user that's joining.

An even better way of doing this would of course be to skip the BigDB load completely if that's possible. Doesn't every player know its own username when it joins? Then you can send that in and broadcast it out to everyone else immediately. :-)
User avatar
Henrik
.IO
 
Posts: 570
Joined: January 4th, 2010, 1:53 pm

Re: String value changing when passed from server to client

Postby Henrik » December 7th, 2011, 3:05 pm

(The last thread you made got duplicated somehow, probably because we were in the process of moving the forum database. The topic is still here, and my reply to that as well: quickconnect-f33/kong-appended-to-kongregate-user-id-t2154)
User avatar
Henrik
.IO
 
Posts: 570
Joined: January 4th, 2010, 1:53 pm

Re: String value changing when passed from server to client

Postby mgray417 » December 7th, 2011, 9:05 pm

Henrik,

Thank you so much for the reply! I'm sorry, I didn't realize the last thread was still up. I'm going to go give this a shot right now.

Fantastic answer, thank you again.

Mike
mgray417
 
Posts: 13
Joined: February 17th, 2010, 10:00 pm


Return to BigDB



cron