Forum Multiplayer Broadcast(myMessage); throws System.NullReferenceException

Discussion and help relating to the PlayerIO Multiplayer API.

Broadcast(myMessage); throws System.NullReferenceException

Postby Deril » September 21st, 2017, 12:43 pm

Hello,

I have strange error crashing my server. Server works fine fo awile(5-15 mins) then crashes randomly:

(I am using Server v3.5.0.0, reproduced both on release and debug servers)

Error log:

Code: Select all
System.NullReferenceException occurred
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Player.IO Development Server
  StackTrace:
   at PlayerIO.ServerCore.SocketLibrary.MessageSerializer.serializeToBytes(Message m, ByteWriter writer)
   at PlayerIO.ServerCore.SocketLibrary.MessagingConnection.Send(Message message)
   at PlayerIO.ServerCore.GameManager.ClientConnection.<>c__DisplayClass13.<Send>b__12()
   at PlayerIO.ServerCore.GameManager.ExternalCodeManager.<>c__DisplayClass7.<PauseToRunOurCode>b__6()
   at PlayerIO.ServerCore.GameManager.ExternalCodeManager.PauseToRunOurCode[T](Func`1 ourCode)
   at PlayerIO.ServerCore.GameManager.ExternalCodeManager.PauseToRunOurCode(Action ourCode)
   at PlayerIO.ServerCore.GameManager.ClientConnection.Send(Message message)
   at PlayerIO.GameLibrary.BasePlayer.Send(Message message)
   at PlayerIO.ServerCore.GameManager.GameHost.Broadcast(Message message, BasePlayer[] players, Int32 playerCount)
   at PlayerIO.GameLibrary.Game`1.Broadcast(Message message)
   at RoomLogics.GameRoom.BroadcastChangeStack() in C:\!intelliSpace\y8Snakes\server\RoomLogics\Src\Core\GameRoom.cs:line 72
   at RoomLogics.GameRoom.<GameStarted>b__17_0() in C:\!intelliSpace\y8Snakes\server\RoomLogics\Src\Core\GameRoom.cs:line 60
   at PlayerIO.ServerCore.GameManager.GameHost.runEvent_(GameEvent evt, BasePlayer player, Message message, Action action)
   at PlayerIO.ServerCore.GameManager.GameHost.<>c__DisplayClass3c.<RunEvent>b__3a()
   at PlayerIO.ServerCore.GameManager.ExternalCodeManager.RunExternalCode[T](UInt32 gameId, Func`1 externalCode, Nullable`1 maxNaturalTimeOverride, Int64& ticks)
   at PlayerIO.ServerCore.GameManager.GameHost.RunEvent(GameEvent evt, BasePlayer player, Message message, Action action)


My line 60:

Code: Select all
AddTimer(delegate { BroadcastChangeStack(); }, 100);


line 72:
Code: Select all
Broadcast(stackMessage);


stackMessage is definetly not null. (I check it in try catch, its non null and had Count = 32

What I am doing is adding all player actions into stackMessage, then sending it to all players every 100 ms. (to reduce bandwidth.) Creating new empty message in place of old one. (stackMessage never set to null in code).

Any ideas what problem it may be? What could I do to investigate it?

Thank you for your time.
Deril
 
Posts: 8
Joined: January 12th, 2017, 1:44 pm

Re: Broadcast(myMessage); throws System.NullReferenceExcepti

Postby Henrik » September 23rd, 2017, 8:27 am

Are you modifying the shared variable stackMessage in multiple places in your code? That will cause a concurrency issue.

Or are perhaps some of the parameters added to the message null?
Henrik
.IO
 
Posts: 1880
Joined: January 4th, 2010, 1:53 pm

Re: Broadcast(myMessage); throws System.NullReferenceExcepti

Postby Deril » October 1st, 2017, 2:29 pm

Thanks for reply,

I had multiply places to modify data, I added semarofs to make sure I have no problems with concurency but that did not help.
Doublechecked that I never write null in.

After many experimentations I am down to this code that throws null object error to me:

Idea is simple:
  • server callects all player movements for 100 ms. Write data to value objects(PlayerMoveData), and Enqueue them to messageQueue.
  • Every 100 ms server empty queue by writing all changes into single message, and broadcasting to all players. (or send "no changes" message)


PROBLEM: for some reasons randomly after 5-10 minutes of gameplay server crashes, Dequeue object from queue returns null. (I never add null into queue with my code.)

Code: Select all

        // queue of value objects holding player move data.
        private Queue<PlayerMoveData> messageQueue = new Queue<PlayerMoveData>();

         // This method is called when a player sends a message into the server code
        public override void GotMessage(MyPlayer player, Message message) {
            switch (message.Type) {
                case ClientMessageType.DO_TURN:
                    DoTurn(player, message);
                    break;
                default:
                    Console.WriteLine("WARNING: not handled message type:" + message.Type);
                    break;
            }
        }

        private void DoTurn(MyPlayer player, Message msg) {
            int nextAngle = msg.GetInt(0);
            int x = msg.GetInt(1);
            int y = msg.GetInt(2);

            messageQueue.Enqueue(new PlayerMoveData(player.id, nextAngle, x, y));
        }


        // This method is called when an instance (gameroom) of your game is created
        public override void GameStarted() {
            ScheduleCallback(BroadcastChangeStack, 100);
        }

        // broadcast all enemy movements to all players every 100 ms
        private void BroadcastChangeStack() {
            if (messageQueue.count > 0) {
                    Message changeStackMessage = Message.Create(ServerMessageType.MOVE_STACK);
                    while (messageQueue.Count > 0) {
                            MessageData data = messageQueue.Dequeue();

                            changeStackMessage.Add(data.id); // CRASH POINT!  data is null.
                            changeStackMessage.Add(data.nextAngle);
                            changeStackMessage.Add(data.x);
                            changeStackMessage.Add(data.y);
                    }
                    Broadcast(changeStackMessage);
            } else {
                    Broadcast(ServerMessageType.NO_CHANGE_PING);
            }
            ScheduleCallback(BroadcastChangeStack, 100);
        }



I dont understand how this even posible...
Deril
 
Posts: 8
Joined: January 12th, 2017, 1:44 pm


Return to Multiplayer



cron