private async void SIOSocketReader() { bool haveIEverBeenConnected = false; while (!cTokenSrc.Token.IsCancellationRequested) { var message = ""; var binary = new List <byte>(); READ: var buffer = new byte[1024]; WebSocketReceiveResult res = null; try { res = await Socket.ReceiveAsync(new ArraySegment <byte>(buffer), cTokenSrc.Token); if (cTokenSrc.Token.IsCancellationRequested) { return; } } catch { if (Status != SIOStatus.CONNECTED) { return; //Yeah, we already know. Wait for reconnect } //Something went wrong if (cTokenSrc.Token.IsCancellationRequested) { return; } if (Status == SIOStatus.CONNECTED) { Socket.Abort(); } Status = SIOStatus.ERROR; SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent((haveIEverBeenConnected ? "disconnect" : (ReconnectAttempts > 0 ? "reconnect_error" : "connect_error")), (Socket.State == WebSocketState.CloseReceived || Socket.State == WebSocketState.Closed ? "transport close" : "transport error")); })); return; } if (res == null) { goto READ; //we got nothing. Wait for data. } if (res.MessageType == WebSocketMessageType.Close) { if (cTokenSrc.Token.IsCancellationRequested || Status != SIOStatus.CONNECTED) { return; } Status = SIOStatus.ERROR; SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent((haveIEverBeenConnected ? "disconnect" : (ReconnectAttempts > 0 ? "reconnect_error" : "connect_error")), "transport close"); })); return; } else if (res.MessageType == WebSocketMessageType.Text) { if (!res.EndOfMessage) { message += Encoding.UTF8.GetString(buffer).TrimEnd('\0'); goto READ; } message += Encoding.UTF8.GetString(buffer).TrimEnd('\0'); #if VERBOSE SocketIOManager.LogDebug("WS < " + message); #endif SocketPacket packet = Decoder.Decode(message); switch (packet.enginePacketType) { case EnginePacketType.OPEN: SocketOpenData sockData = JsonUtility.FromJson <SocketOpenData>(packet.json); SocketID = null; pingInterval = sockData.pingInterval; pingTimeout = sockData.pingTimeout; //Serialize Payload string payload = ""; if (authPayload != null) { payload = authPayload.GetPayloadJSON(); } //Hey Server, how are you today? EmitPacket(new SocketPacket(EnginePacketType.MESSAGE, SocketPacketType.CONNECT, 0, "/", -1, payload)); SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("open"); })); break; case EnginePacketType.CLOSE: SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("close"); })); break; case EnginePacketType.MESSAGE: if (packet.socketPacketType == SocketPacketType.EVENT && packet.json == "") { buffer = null; message = ""; continue; } if (packet.socketPacketType == SocketPacketType.CONNECT) { //Extract socket id string tmpExtractionSubstr = packet.json.Substring(packet.json.IndexOf("sid\":") + 4).Trim(); tmpExtractionSubstr = tmpExtractionSubstr.Substring(tmpExtractionSubstr.IndexOf("\"") + 1, tmpExtractionSubstr.IndexOf("}") - 1); SocketID = tmpExtractionSubstr.Substring(0, tmpExtractionSubstr.IndexOf("\"")); //invoke "connect" event Status = SIOStatus.CONNECTED; if (ReconnectAttempts > 0) { SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("reconnect", null); })); } SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("connect", null); })); haveIEverBeenConnected = true; ReconnectAttempts = 0; } else if (packet.socketPacketType == SocketPacketType.DISCONNECT) { SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("disconnect", "io server disconnect"); })); FinishOperation(); } else if (packet.socketPacketType == SocketPacketType.ACK) { SocketIOManager.LogWarning("ACK is not supported by this library."); } else if (packet.socketPacketType == SocketPacketType.EVENT) { SIOEventStructure e = Parser.Parse(packet.json); SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent(e.eventName, e.data); })); } break; case EnginePacketType.PING: lastPing = DateTime.Now; EmitPacket(new SocketPacket(EnginePacketType.PONG)); break; default: SocketIOManager.LogWarning("Unhandled SIO packet: " + message); break; } } else { if (!res.EndOfMessage) { goto READ; } SocketIOManager.LogWarning("Received binary message"); } buffer = null; } }
private async void SIOSocketReader() { while (!cTokenSrc.IsCancellationRequested) { var message = ""; var binary = new List <byte>(); READ: var buffer = new byte[1024]; WebSocketReceiveResult res = null; try { res = await Socket.ReceiveAsync(new ArraySegment <byte>(buffer), cTokenSrc.Token); if (cTokenSrc.IsCancellationRequested) { return; } } catch { //Something went wrong if (cTokenSrc.IsCancellationRequested) { return; } Status = SIOStatus.ERROR; SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("disconnect", "server namespace disconnect"); })); Socket.Abort(); break; } if (res == null) { goto READ; //we got nothing. Wait for data. } if (res.MessageType == WebSocketMessageType.Close) { cTokenSrc.Cancel(); Status = SIOStatus.DISCONNECTED; SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("disconnect", "server namespace disconnect"); })); return; } else if (res.MessageType == WebSocketMessageType.Text) { if (!res.EndOfMessage) { message += Encoding.UTF8.GetString(buffer).TrimEnd('\0'); goto READ; } message += Encoding.UTF8.GetString(buffer).TrimEnd('\0'); SocketPacket packet = Decoder.Decode(message); switch (packet.enginePacketType) { case EnginePacketType.OPEN: SocketID = JsonUtility.FromJson <SocketOpenData>(packet.json).sid; SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("open"); })); break; case EnginePacketType.CLOSE: SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent("close"); })); break; case EnginePacketType.MESSAGE: if (packet.json == "") { buffer = null; message = ""; continue; } if (packet.socketPacketType == SocketPacketType.ACK) { SocketIOManager.LogWarning("ACK is not supported by this library."); } if (packet.socketPacketType == SocketPacketType.EVENT) { SIOEventStructure e = Parser.Parse(packet.json); SIODispatcher.Instance.Enqueue(new Action(() => { RaiseSIOEvent(e.eventName, e.data); })); } break; case EnginePacketType.PING: EmitPacket(new SocketPacket(EnginePacketType.PONG)); break; case EnginePacketType.PONG: waitingForPong = false; //woohoo! break; default: SocketIOManager.LogWarning("Unhandled SIO packet: " + message); break; } } else { if (!res.EndOfMessage) { goto READ; } SocketIOManager.LogWarning("Received binary message"); } buffer = null; } }