missing incoming unreliable events

Options
terdos
edited September 2013 in DotNet
For a project I am working on I was experimenting with using unreliable events for player updates. I have noticed that if more than one unreliable event is processed by the client in the same call to DispatchIncomingCommands() typically only one of the events is forwarded to the OnEvent handler.

I am currently using Unity / LoadBalancingPeer for my current tests.

I am seeing log messages:
ALL queueIncomingCommand( NC(1|7 r/u: 0/30 st/r#/rt:0/0/0) )  -  incomingReliableSequenceNumber: 0
ALL unreliable. local: 0/29 incoming: 0/30
ALL queueIncomingCommand( NC(2|7 r/u: 0/30 st/r#/rt:0/0/0) )  -  incomingReliableSequenceNumber: 0
ALL unreliable. local: 0/29 incoming: 0/30
On Event 2

which is why I am assuming I am receiving two events from the server. however only the second one is forwarded to OnEvent.

The code used to generate the events is:
  Hashtable t = new Hashtable();

  t[(byte)0] = client.LocalTimeInMilliSeconds;
  t[(byte)1] = 1 ;

  client.OpRaiseEvent((byte)1, t, false, (byte)1 , new int[] {client.LocalPlayer.ID});

  t = new Hashtable();

  t[(byte)0] = client.LocalTimeInMilliSeconds;
  t[(byte)1] = 2 ;

  client.OpRaiseEvent((byte)2, t, false, (byte)2 , new int[] {client.LocalPlayer.ID});
   
  client.SendOutgoingCommands();                

and my OnEvent:
  Debug.Log ("On Event " + photonEvent.Code);

If I send the events on the same channel I will always receive both, If set them both to reliable I will always receive both, but if I send them on different channels unreliable, the only way I recevie both is if they arrive at the client in different frames. or so it appears.

What is happening does not make sense, with my current understanding of sequencing/channels/unreliable events.

I am just wondering if I am missing a configuration or am misunderstanding the architecture.

Comments

  • dreamora
    dreamora
    edited June 2012
    Options
    Thats normal assuming the two messages are follow ups of the same 'message type' (type of message and covering the same object etc), it would then be the expected and desired result (its one of the reasons why unrealiable messages are used)

    If you have unreliable messages and 2 of the same type are received during one frame then only the latest one is handled, all previous ones are discarded as they are 'outdated'. The same happens to all events of this type that are older and come in later.
    Its always the latest one that defines the 'min index' for a message to be accepted.

    For the technical rest see Tobias answer below
  • Tobias
    Options
    If I send the events on the same channel I will always receive both, If set them both to reliable I will always receive both, but if I send them on different channels unreliable, the only way I recevie both is if they arrive at the client in different frames. or so it appears.

    First off: Unreliably sent commands are never guaranteed to arrive. It is maybe interesting to find out how many are missing but it's normal that they might get dropped. Aside from "the network dropped some", there are several other possible causes.
    Some insight (but really short):

    DispatchIncomingCommands will only dispatch a single command/message/incoming-event per call.
    We recently implemented a configuration to limit the queue of unreliable commands. In case you received a whole lot of those, it helps skip the older ones and "get to the point" with more recent updates (of unreliable info). The PhotonPeer.LimitOfUnreliableCommands is by default 20.
    Unreliable commands are in-sequence with reliable commands in the same channel. This way, unreliable commands can't overtake events you flagged as reliable. On the other hand, unreliable commands that happened before a certain reliable command are discarded when that reliable command is already dispatched.

    If neither explains your issue, let us know and we will take another look.
  • terdos
    Options
    Thanks for your replies.

    I am currently doing most of my testing on a local machine so I would expect a minimal amount of packets to be dropped by the network. If I am reading the logs correctly I am typically seeing all my events arrive.

    I currently have DispatchIncomingCommands in a while loop to ensure that was not the problem. But if it were, the messages would be processed the next frame anyway.

    In my tests there were no reliable messages other than control sequences (connect, authenticate, join, etc). I have read the documentation so I know how reliable and unreliable they are supposed to interact (or at least think I do)

    My problem that I see is I am raising two different events (event 1 and event 2) in two different channels (channel 1 and channel 2) as can be seen in the code above. But I am only receiving the event for one of them. I can understand dropping older events of the same type, but what I am sending should be considered different events. It does occur to me however that OpRaiseEvent is using OpCustom(OperationCode.RaiseEvent,...) under the hood so, it is possible that all events I raise are considered the same operation and therefore droppable. Could this be what is going on?
  • Tobias
    Options
    > it is possible that all events I raise are considered the same operation and therefore droppable. Could this be what is going on?
    No. You can send the very same event as many times as you wanted to, if necessary. There is no check of content.

    I will take another look tomorrow.
  • Tobias
    Options
    Found the bug and fixed it.
    Please download the v3.0.1.11 SDK for this fix.

    Sorry for the inconvenience and thanks for posting this.
  • terdos
    Options
    My events are now working as expected.

    Thank you very much :)
  • Is the following true ?

    unreliable events sent on channelid 0 will be sent ahead of reliable operations on channelid 1 ?
  • Tobias
    Options
    Yes.
    Different channels are totally independent from each other as sequence but we start sending commands of channel 0 going up.