async Task ReadLoopAsync() { await Task.Yield(); while (true) { //TODO: if not cached , and all stream closed , shutdown directly var data = await ReceiveAsync(); if (data == null) { Console.WriteLine("_udp.ReceiveAsync() return null ,Close()"); Close(); return; } long sid = BitConverter.ToInt64(data, 8); if (sid == -1) { Console.WriteLine("_udp.ReceiveAsync() return " + sid + ", " + UDPMeta.GetPackageType(data)); } UDPBufferReader reader = GetBufferReader(sid); reader.OnPost(data); } }
void ClientWorkThread() { try { while (true) { //TODO:when timeout , try to send idle message byte[] data = _udp.Receive(SessionId, TimeSpan.FromSeconds(40)); if (data == null) { if (!_reader._removed) { Console.WriteLine("UDPClientStream.ClientWorkThread.Timeout-40"); } _reader.OnRemoved(); base.OnWorkerThreadExit(); return; } try { UDPPackageType pt = UDPMeta.GetPackageType(data); ProcessUDPPackage(pt, data); } catch (Exception x) { TcpMapService.OnError(x); } } } catch (Exception x) { TcpMapService.OnError(x); } }
void ListenerWorkThread() { while (this._workthread != null) { try { //TODO: if not cached , and all stream closed , shutdown directly IPEndPoint ep; byte[] data = _udp.Receive(TimeSpan.FromSeconds(90), out ep); if (data == null) { Console.WriteLine("_udp.Receive return null for a long time...; Shutdown..." + this._udp.LocalEndPoint); this.Close(); return; } UDPPackageType pt = UDPMeta.GetPackageType(data); if (pt == UDPPackageType.Unknown) { //Console.WriteLine("_udp.Receive return Unknown;"); return; } long sid = BitConverter.ToInt64(data, 8); ServerStream ss; //Console.WriteLine("_udp.Receive " + sid + ":" + pt); if (pt == UDPPackageType.SessionConnect) { UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16)); lock (strmap) { if (!strmap.TryGetValue(sid, out ss)) { ss = new ServerStream(this, sid, ep, udpc); strmap[sid] = ss; } } if (ss.ConnectToken != udpc.token) { ss.ForceClose(); lock (strmap) { ss = new ServerStream(this, sid, ep, udpc); strmap[sid] = ss; } } else { ss.Process(pt, data); } } else { lock (strmap) { strmap.TryGetValue(sid, out ss); } if (ss != null) { ss.Process(pt, data); } else { _udp.SendToClient(ep, UDPMeta.CreateSessionError(sid, "NotFound")); } } } catch (ThreadAbortException) { break; } catch (Exception x) { TcpMapService.OnError(x); } } }
void _Connect(UDPClientListener udp, string ip, int port, TimeSpan timeout) { _udp = udp; StartConnect: SessionId = Interlocked.Increment(ref _nextsessionid); string guid = Guid.NewGuid().ToString(); byte[] buffconnect = UDPMeta.CreateSessionConnect(SessionId, guid); SendToPeer(buffconnect); SendToPeer(buffconnect); while (true) { byte[] buffprepair = _udp.Receive(SessionId, TimeSpan.FromMilliseconds(500)); if (buffprepair == null) { CheckTimeout(timeout); Console.WriteLine("Client StartConnect Again"); //SendToPeer(buffconnect); SendToPeer(buffconnect); //continue; goto StartConnect; } UDPPackageType ptprepair = UDPMeta.GetPackageType(buffprepair); if (ptprepair != UDPPackageType.SessionPrepair) { if (ptprepair > UDPPackageType.SessionPrepair) { goto StartConnect; } continue; } long sidprepair = BitConverter.ToInt64(buffprepair, 8); if (sidprepair != SessionId) { goto StartConnect; } UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(buffprepair, 16, buffprepair.Length - 16)); if (udpc.token != guid) { goto StartConnect; } break; } byte[] buffconfirm = UDPMeta.CreateSessionConfirm(SessionId, guid); SendToPeer(buffconfirm); SendToPeer(buffconfirm); while (true) { byte[] buffready = _udp.Receive(SessionId, TimeSpan.FromMilliseconds(500)); if (buffready == null) { CheckTimeout(timeout); SendToPeer(buffconfirm); SendToPeer(buffconfirm); continue; } UDPPackageType ptprepair = UDPMeta.GetPackageType(buffready); if (ptprepair != UDPPackageType.SessionReady) { if (ptprepair > UDPPackageType.SessionReady) { goto StartConnect; } continue; } long sidprepair = BitConverter.ToInt64(buffready, 8); if (sidprepair != SessionId) { goto StartConnect; } UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(buffready, 16, buffready.Length - 16)); if (udpc.token != guid) { goto StartConnect; } break; } _reader = new ClientBufferReader(); Thread t = new Thread(ClientWorkThread); //TODO:Convert to async t.IsBackground = true; t.Start(); }