Author Topic: Some players can't see each other in same channel  (Read 4038 times)

gg67

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 66
    • View Profile
Some players can't see each other in same channel
« on: February 10, 2014, 11:52:00 AM »
Hey Aren,

I've come across an issue where I have ~20 people in a channel where some players can see everybody, but a some players cannot see a few specific individuals. This is occurring with a public channel that I've given the channel ID of 1 to. Also, sometimes users cannot connect to the room for some unexplained reason. Is there something wrong with assigning a specific ID to a channel? Another possible symptom is that whenever I quit the application out of that level, I get multiple "m_InstanceID == 0" errors that I can't figure out where they come from

I also ran into a few server crashes, giving the following error:

  1. Unhandled Exception: System.Net.Sockets.SocketException: An existing connection
  2. was forcibly closed by the remote host
  3.    at System.Net.Sockets.Socket.BeginSend(Byte[] buffer, Int32 offset, Int32 siz
  4. e, SocketFlags socketFlags, AsyncCallback callback, Object state)
  5.    at TNet.TcpProtocol.OnSend(IAsyncResult result) in C:\Users\Graham\Developer\
  6. tnet\Assets\TNet\Common\TNTcpProtocol.cs:line 456
  7.    at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
  8.    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
  9. ontextCallback callback, Object state)
  10.    at System.Net.ContextAwareResult.Complete(IntPtr userToken)
  11.    at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr u
  12. serToken)
  13.    at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32
  14.  errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
  15.    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32
  16. errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

Thanks
« Last Edit: February 10, 2014, 05:03:53 PM by gg67 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Some players can't see each other in same channel
« Reply #1 on: February 10, 2014, 05:58:40 PM »
You can assign specific IDs to channels, that's fine. Are you sending anything via SendQuickly where players can't see some individuals?

m_InstanceID == 0 is something in Unity, and would be related to what you're doing in your game.

As for the exception... curious. Try wrapping it into a try/catch block:
  1.         void OnSend (IAsyncResult result)
  2.         {
  3.                 if (stage == Stage.NotConnected) return;
  4.                 int bytes;
  5.                
  6.                 try
  7.                 {
  8.                         bytes = mSocket.EndSend(result);
  9.                 }
  10.                 catch (System.Exception ex)
  11.                 {
  12.                         bytes = 0;
  13.                         Close(true);
  14.                         Error(ex.Message);
  15.                         return;
  16.                 }
  17.  
  18.                 lock (mOut)
  19.                 {
  20.                         // The buffer has been sent and can now be safely recycled
  21.                         mOut.Dequeue().Recycle();
  22.  
  23.                         if (bytes > 0 && mSocket != null && mSocket.Connected)
  24.                         {
  25.                                 // If there is another packet to send out, let's send it
  26.                                 Buffer next = (mOut.Count == 0) ? null : mOut.Peek();
  27.  
  28.                                 if (next != null)
  29.                                 {
  30.                                         try
  31.                                         {
  32.                                                 mSocket.BeginSend(next.buffer, next.position, next.size, SocketFlags.None, OnSend, next);
  33.                                         }
  34.                                         catch (Exception ex)
  35.                                         {
  36.                                                 Error(ex.Message);
  37.                                                 Close(false);
  38.                                         }
  39.                                 }
  40.                         }
  41.                         else Close(true);
  42.                 }
  43.         }

gg67

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 66
    • View Profile
Re: Some players can't see each other in same channel
« Reply #2 on: February 10, 2014, 10:20:46 PM »
I'm not sending anything using SendQuickly (I thought we decided it was unreliable right now sometime and shouldn't be used yet?), but could the players not seeing each other have something to do with the time it takes to load the level and the RFCs being off sync?

What is the order of operations when joining a channel? Join Channel, Load Level, Receive/Send stored RFCs?
If everybody is in the same channel, and player A can see player B but player B can't see player A, then wouldn't that have to do with the RFC for creating an object in the TNAutoCreate?

« Last Edit: February 11, 2014, 12:30:31 PM by gg67 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Some players can't see each other in same channel
« Reply #3 on: February 11, 2014, 09:19:38 PM »
The order is:

1. Join a channel
2. Load level
3. Execute RFCs
4. Only then does OnNetworkJoinChannel() get sent out.

Only once you receive OnNetworkJoinChannel can you start doing your game logic.

TNAutoCreate should work just fine and consistently. All it does is uses TNManager.Create inside to spawn something. Just make sure that whatever is being spawned has a dynamic ID (prefab's TNObject ID is 0).

The application is supposed to be paused while doing Application.LoadLevel. If you're doing any kind of asynchronous loading, or if it's not actually paused, you can always pause TNet's message processing (TNManager.isActive = false;). You can do this in some object's Awake() function, and set it back to 'true' when you get the OnNetworkJoinChannel (note: I haven't tried doing that myself though, so keep that in mind)

gg67

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 66
    • View Profile
Re: Some players can't see each other in same channel
« Reply #4 on: February 11, 2014, 09:37:13 PM »
I'm using TNAutoCreate to instantiate players. Does that wait for OnNetworkJoinChannel before creating stuff?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Some players can't see each other in same channel
« Reply #5 on: February 11, 2014, 09:41:23 PM »
Other players' TNAutoCreate calls result in TNManager.Create, which execute before the join notification. Local script spawns a new player only after the join notification.

gg67

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 66
    • View Profile
Re: Some players can't see each other in same channel
« Reply #6 on: February 11, 2014, 09:50:39 PM »
I don't think I follow.
Quote
Local script spawns a new player only after the join notification.
Confuses me.

When I spawn a player using TNAutoCreate, is there anything special I need to do for other players to register them? And as for the newly instantiated player, by the time the Start and Awake methods are fired, that player is registered in the channel so I shouldn't have to do anything other than put my setup code in the appropriate Start/Awake?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Some players can't see each other in same channel
« Reply #7 on: February 13, 2014, 03:28:39 AM »
Well, look at the TNAutoCreate script:
  1. public class TNAutoCreate : MonoBehaviour
  2. {
  3.         /// <summary>
  4.         /// Prefab to instantiate.
  5.         /// </summary>
  6.  
  7.         public GameObject prefab;
  8.  
  9.         /// <summary>
  10.         /// Whether the instantiated object will remain in the game when the player that created it leaves.
  11.         /// Set this to 'false' for the player's avatar.
  12.         /// </summary>
  13.  
  14.         public bool persistent = false;
  15.  
  16.         void Start ()
  17.         {
  18.                 TNManager.Create(prefab, transform.position, transform.rotation, persistent);
  19.                 Destroy(gameObject);
  20.         }
  21. }
All it does inside is creates the object in its Start() function -- which executes only after the level has finished loading.

This results in a message that gets sent to the server, and when the response comes, it will arrive in the queue only after all the other messages.

There is nothing special required. It's a very simple script.

Start() and especially Awake() can (and do) fire before OnNetworkJoinChannel notification. This is why everything related to game logic should wait for OnNetworkJoinChannel notification to arrive first. Only after it arrives can you consider yourself being truly "there" in the channel.