/// <summary> /// used by TPeer* /// </summary> public override PhotonSocketError Send(byte[] data, int length) { if (this.State != PhotonSocketState.Connected) { return(PhotonSocketError.Skipped); } try { if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "Sending: " + SupportClassPun.ByteArrayToString(data)); } if (this.sock != null) { this.sock.Send(data); } } catch (Exception e) { this.Listener.DebugReturn(DebugLevel.ERROR, "Cannot send to: " + this.ConnectAddress + ". " + e.Message); this.HandleException(StatusCode.Exception); return(PhotonSocketError.Exception); } return(PhotonSocketError.Success); }
/// <summary>Called by Unity when the application is closed. Disconnects.</summary> protected virtual void OnApplicationQuit() { //Debug.Log("OnApplicationQuit"); this.StopFallbackSendAckThread(); if (this.Client != null) { this.Client.Disconnect(); } SupportClass.StopAllBackgroundCalls(); }
public void StartFallbackSendAckThread() { #if !UNITY_WEBGL if (this.FallbackThreadRunning) { return; } this.fallbackThreadId = SupportClass.StartBackgroundCalls(this.RealtimeFallbackThread, 50, "RealtimeFallbackThread"); #endif }
public void StopFallbackSendAckThread() { #if !UNITY_WEBGL if (!this.FallbackThreadRunning) { return; } SupportClass.StopBackgroundCalls(this.fallbackThreadId); this.fallbackThreadId = 255; #endif }
/// <summary>Called by Unity when the application gets closed. Disconnects if OnApplicationQuit() was called before.</summary> protected virtual void OnDisable() { this.StopFallbackSendAckThread(); if (AppQuits) { if (this.Client != null && this.Client.IsConnected) { this.Client.Disconnect(); this.Client.LoadBalancingPeer.StopThread(); } SupportClass.StopAllBackgroundCalls(); } }
public void StartFallbackSendAckThread() { #if !UNITY_WEBGL if (this.FallbackThreadRunning) { return; } #if UNITY_SWITCH this.fallbackThreadId = SupportClass.StartBackgroundCalls(this.RealtimeFallbackThread, 50); // as workaround, we don't name the Thread. #else this.fallbackThreadId = SupportClass.StartBackgroundCalls(this.RealtimeFallbackThread, 50, "RealtimeFallbackThread"); #endif #endif }
/// <summary> /// used by TPeer* /// </summary> public override PhotonSocketError Send(byte[] data, int length) { if (this.State != PhotonSocketState.Connected) { return PhotonSocketError.Skipped; } try { if (data.Length > length) { byte[] trimmedData = new byte[length]; Buffer.BlockCopy(data, 0, trimmedData, 0, length); data = trimmedData; } if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "Sending: " + SupportClassPun.ByteArrayToString(data)); } if (this.sock != null) { this.sock.Send(data); } } catch (Exception e) { this.Listener.DebugReturn(DebugLevel.ERROR, "Cannot send to: " + this.ServerAddress + ". " + e.Message); this.HandleException(StatusCode.Exception); return PhotonSocketError.Exception; } return PhotonSocketError.Success; }
/// <summary>Returns most interesting room values as string, including custom properties.</summary> /// <returns>Summary of this RoomInfo instance.</returns> public string ToStringFull() { return(string.Format("Room: '{0}' {1},{2} {4}/{3} players.\ncustomProps: {5}", this.name, this.isVisible ? "visible" : "hidden", this.isOpen ? "open" : "closed", this.maxPlayers, this.PlayerCount, SupportClass.DictionaryToString(this.customProperties))); }
public IEnumerator ReceiveLoop() { //this.Listener.DebugReturn(DebugLevel.INFO, "ReceiveLoop()"); if (this.sock != null) { while (this.sock != null && !this.sock.Connected && this.sock.Error == null) { yield return(new WaitForRealSeconds(0.1f)); } if (this.sock != null) { if (this.sock.Error != null) { this.Listener.DebugReturn(DebugLevel.ERROR, "Exiting receive thread. Server: " + this.ServerAddress + ":" + this.ServerPort + " Error: " + this.sock.Error); this.HandleException(StatusCode.ExceptionOnConnect); } else { // connected if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "Receiving by websocket. this.State: " + this.State); } this.State = PhotonSocketState.Connected; while (this.State == PhotonSocketState.Connected) { if (this.sock != null) { if (this.sock.Error != null) { this.Listener.DebugReturn(DebugLevel.ERROR, "Exiting receive thread (inside loop). Server: " + this.ServerAddress + ":" + this.ServerPort + " Error: " + this.sock.Error); this.HandleException(StatusCode.ExceptionOnReceive); break; } else { byte[] inBuff = this.sock.Recv(); if (inBuff == null || inBuff.Length == 0) { // nothing received. wait a bit, try again yield return(new WaitForRealSeconds(0.02f)); continue; } if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "TCP << " + inBuff.Length + " = " + SupportClassPun.ByteArrayToString(inBuff)); } if (inBuff.Length > 0) { try { this.HandleReceivedDatagram(inBuff, inBuff.Length, false); } catch (Exception e) { if (this.State != PhotonSocketState.Disconnecting && this.State != PhotonSocketState.Disconnected) { if (this.ReportDebugOfLevel(DebugLevel.ERROR)) { this.EnqueueDebugReturn(DebugLevel.ERROR, "Receive issue. State: " + this.State + ". Server: '" + this.ServerAddress + "' Exception: " + e); } this.HandleException(StatusCode.ExceptionOnReceive); } } } } } } } } } this.Disconnect(); }
public IEnumerator ReceiveLoop() { if (this.sock != null) { this.sock.Connect(); while (this.sock != null && !this.sock.Connected && this.sock.Error == null) { #if UNITY_5_3 || UNITY_5_3_OR_NEWER yield return(new WaitForRealSeconds(0.02f)); #else float waittime = Time.realtimeSinceStartup + 0.2f; while (Time.realtimeSinceStartup < waittime) { yield return(0); } #endif } if (this.sock != null) { if (this.sock.Error != null) { this.Listener.DebugReturn(DebugLevel.ERROR, "Exiting receive thread. Server: " + this.ConnectAddress + " Error: " + this.sock.Error); this.HandleException(StatusCode.ExceptionOnConnect); } else { // connected this.State = PhotonSocketState.Connected; this.peerBase.OnConnect(); while (this.State == PhotonSocketState.Connected) { if (this.sock != null) { if (this.sock.Error != null) { this.Listener.DebugReturn(DebugLevel.ERROR, "Exiting receive thread (inside loop). Server: " + this.ConnectAddress + " Error: " + this.sock.Error); this.HandleException(StatusCode.ExceptionOnReceive); break; } else { byte[] inBuff = this.sock.Recv(); if (inBuff == null || inBuff.Length == 0) { // nothing received. wait a bit, try again #if UNITY_5_3 || UNITY_5_3_OR_NEWER yield return(new WaitForRealSeconds(0.02f)); #else float waittime = Time.realtimeSinceStartup + 0.02f; while (Time.realtimeSinceStartup < waittime) { yield return(0); } #endif continue; } if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "TCP << " + inBuff.Length + " = " + SupportClassPun.ByteArrayToString(inBuff)); } if (inBuff.Length > 0) { try { HandleReceivedDatagram(inBuff, inBuff.Length, false); } catch (Exception e) { if (this.State != PhotonSocketState.Disconnecting && this.State != PhotonSocketState.Disconnected) { if (this.ReportDebugOfLevel(DebugLevel.ERROR)) { this.EnqueueDebugReturn(DebugLevel.ERROR, "Receive issue. State: " + this.State + ". Server: '" + this.ConnectAddress + "' Exception: " + e); } this.HandleException(StatusCode.ExceptionOnReceive); } } } } } } } } } this.Disconnect(); }
/// <summary>Helper method for debugging of IDictionary content, inlcuding type-information. Using this is not performant.</summary> /// <remarks>Should only be used for debugging as necessary.</remarks> /// <param name="origin">Some Dictionary or Hashtable.</param> /// <returns>String of the content of the IDictionary.</returns> public static string ToStringFull(this IDictionary origin) { return(SupportClass.DictionaryToString(origin, false)); }
public IEnumerator ReceiveLoop() { this.Listener.DebugReturn(DebugLevel.INFO, "ReceiveLoop()"); while (!this.sock.Connected && this.sock.Error == null) { yield return(new WaitForSeconds(0.1f)); } if (this.sock.Error != null) { this.Listener.DebugReturn(DebugLevel.ERROR, "Exiting receive thread due to error: " + this.sock.Error + " Server: " + this.ServerAddress); this.HandleException(StatusCode.ExceptionOnConnect); } else { if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "Receiving by websocket. this.State: " + State); } State = PhotonSocketState.Connected; while (State == PhotonSocketState.Connected) { if (this.sock.Error != null) { this.Listener.DebugReturn(DebugLevel.ERROR, "Exiting receive thread (inside loop) due to error: " + this.sock.Error + " Server: " + this.ServerAddress); this.HandleException(StatusCode.ExceptionOnReceive); break; } else { byte[] inBuff = this.sock.Recv(); if (inBuff == null || inBuff.Length == 0) { yield return(new WaitForSeconds(0.1f)); continue; } if (this.ReportDebugOfLevel(DebugLevel.ALL)) { this.Listener.DebugReturn(DebugLevel.ALL, "TCP << " + inBuff.Length + " = " + SupportClassPun.ByteArrayToString(inBuff)); } // check if it's a ping-result (first byte = 0xF0). this is 9 bytes in total. no other headers! // note: its a coincidence that ping-result-size == header-size. if this changes we have to refactor this if (inBuff[0] == 0xF0) { try { HandleReceivedDatagram(inBuff, inBuff.Length, false); } catch (Exception e) { if (this.ReportDebugOfLevel(DebugLevel.ERROR)) { this.EnqueueDebugReturn(DebugLevel.ERROR, "Receive issue. State: " + this.State + ". Server: '" + this.ServerAddress + "' Exception: " + e); } this.HandleException(StatusCode.ExceptionOnReceive); } continue; } // get data and split the datagram into two buffers: head and body if (inBuff.Length > 0) { try { HandleReceivedDatagram(inBuff, inBuff.Length, false); } catch (Exception e) { if (this.ReportDebugOfLevel(DebugLevel.ERROR)) { this.EnqueueDebugReturn(DebugLevel.ERROR, "Receive issue. State: " + this.State + ". Server: '" + this.ServerAddress + "' Exception: " + e); } this.HandleException(StatusCode.ExceptionOnReceive); } } } } } Disconnect(); }
/// <summary> /// Brief summary string of the Player. Includes name or player.ID and if it's the Master Client. /// </summary> public override string ToString() { return((string.IsNullOrEmpty(this.NickName) ? this.ActorNumber.ToString() : this.nickName) + " " + SupportClass.DictionaryToString(this.CustomProperties)); }