protected override async Task <CommandMessage> ReadMessageAsync() { if (this.sread == null) { await this.WaitForAttachAsync(); } ReadAgain: var msg = await CommandMessage.ReadFromStreamAsync(this.sread); if (msg == null || msg.Name == "data") { return(msg); } //TcpMapService.LogMessage("ServerSession:get message " + msg); switch (msg.Name) { case "_ping_": await this.swrite.WriteAsync(new CommandMessage("_ping_result_").Pack()); break; case "_ping_result_": break; default: TcpMapService.LogMessage("Error: 6 Ignore message " + msg); break; } goto ReadAgain; }
async Task SessionToStreamAsync(Stream stream) { try { while (true) { //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync"); var msg = await ReadMessageAsync(); //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync DONE : " + msg); if (msg == null) { return; } if (msg.Name == "data") { await stream.WriteAsync(msg.Data); } else { TcpMapService.LogMessage("Warning:this message shall not pass to BaseSession : " + msg); } //TcpMapService.LogMessage(this.GetType().Name + " WriteAsync DONE : " + msg); } } catch (Exception x) { //TcpMapService.OnError(x); } finally { //TcpMapService.LogMessage(this.GetType().Name + " EXITING SessionToStreamAsync"); } }
protected override async Task <CommandMessage> ReadMessageAsync() { ReadAgain: CommandMessage msg; CancellationTokenSource cts = null; if (DateTime.Now - _lastwritetime > TimeSpan.FromMilliseconds(12000)) { _lastwritetime = DateTime.Now; await _swrite.WriteAsync(new CommandMessage("_ping_", "forwrite").Pack()); } else { cts = new CancellationTokenSource(); _ = Task.Run(async delegate { if (await cts.Token.WaitForSignalSettedAsync(16000)) { return; } _lastwritetime = DateTime.Now; await _swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack()); }); } try { msg = await CommandMessage.ReadFromStreamAsync(_sread); } finally { if (cts != null) { cts.Cancel(); } } if (msg == null || msg.Name == "data") { return(msg); } //TcpMapService.LogMessage("ClientSession:get message " + msg); switch (msg.Name) { case "_ping_": await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack()); break; case "_ping_result_": break; default: TcpMapService.LogMessage("Error: 2 Ignore message " + msg); break; } goto ReadAgain; }
public void LogMessage(string msg) { this.logMessages.Enqueue(msg); while (this.logMessages.Count > 200) { this.logMessages.TryDequeue(out _); } TcpMapService.LogMessage(msg); }
protected override async Task<CommandMessage> ReadMessageAsync() { ReadAgain: CommandMessage msg; var cts = new CancellationTokenSource(); _ = Task.Run(async delegate { if (await cts.Token.WaitForSignalSettedAsync(16000)) return; try { await _swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack()); } catch (Exception x) { OnError(x); } }); try { msg = await CommandMessage.ReadFromStreamAsync(_sread); } finally { cts.Cancel(); } if (msg == null || msg.Name == "data") return msg; //TcpMapService.LogMessage("ServerSession:get message " + msg); switch (msg.Name) { case "_ping_": await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack()); break; case "_ping_result_": break; default: TcpMapService.LogMessage("Error: 3 Ignore message " + msg); break; } goto ReadAgain; }
private async Task SessionToStreamAsync(Stream stream) { try { while (true) { //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync"); var msg = await this.ReadMessageAsync(); if (msg == null) { return; } if (msg.Name == "data") { //TcpMapService.LogMessage(this.GetType().Name + " ReadMessageAsync DONE : " + msg); //TcpMapService.LogMessage("Data:" + Encoding.UTF8.GetString(msg.Data.ToArray())); await stream.WriteAsync(msg.Data); } else { TcpMapService.LogMessage("Warning:this message shall not pass to BaseSession : " + msg); } //TcpMapService.LogMessage(this.GetType().Name + " WriteAsync DONE : " + msg); } } catch (ObjectDisposedException) { //no log } catch (Exception) { //TcpMapService.OnError(x); } finally { //TcpMapService.LogMessage(this.GetType().Name + " EXITING SessionToStreamAsync"); } }
private async Task WorkAsync() { this.IsConnected = false; this.LogMessage("ClientWorker WorkAsync start"); int connectedTimes = 0; try { int againTimeout = 125; StartAgain: this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.socket.InitTcp(); this.cts_connect = new CancellationTokenSource(); try { await this.socket.ConnectAsync(this.Client.ServerHost, 6022); this.LogMessage("connected to 6022"); } catch (Exception x) { this.OnError(x); this.socket.CloseSocket(); this.socket = null; this.cts_connect = new CancellationTokenSource(); if (!this.IsStarted) { return; } if (againTimeout < 4) { againTimeout *= 2; } if (await this.cts_connect.Token.WaitForSignalSettedAsync(againTimeout)) { return; } goto StartAgain; } try { bool supportEncrypt = this.Client.UseEncrypt; byte[] clientKeyIV; { CommandMessage connmsg = new CommandMessage { Name = "ClientConnect" }; List <string> arglist = new List <string> { this.Client.License.Key, this.Client.ServerPort.ToString() }; this.Client.License.GenerateSecureKeyAndHash(out clientKeyIV, out byte[] encryptedKeyIV, out byte[] sourceHash); arglist.Add(Convert.ToBase64String(encryptedKeyIV)); arglist.Add(Convert.ToBase64String(sourceHash)); arglist.Add(supportEncrypt ? "1" : "0"); connmsg.Args = arglist.ToArray(); await this.socket.SendAsync(connmsg.Pack(), SocketFlags.None); //LogMessage("wait for conn msg"); connmsg = await CommandMessage.ReadFromSocketAsync(this.socket); if (connmsg == null) { TcpMapService.LogMessage("no message ? Connected:" + this.socket.Connected); return; } this.LogMessage("connmsg : " + connmsg.Name + " : " + string.Join(",", connmsg.Args)); if (connmsg.Name != "ConnectOK") { this.IsStarted = false;//don't go until start it again. throw new Exception(connmsg.Name + " : " + string.Join(",", connmsg.Args)); } if (supportEncrypt && connmsg.Args[1] == "0") { supportEncrypt = false; this.LogMessage("Warning:server don't support encryption."); } } this.IsConnected = true; connectedTimes++; this.LogMessage("ConnectOK #" + connectedTimes); if (supportEncrypt) { this.Client.License.OverrideStream(this.socket.CreateStream(), clientKeyIV, out this.sread, out this.swrite); } else { this.sread = this.swrite = this.socket.CreateStream(); } for (int i = 0; i < Math.Min(5, this.Client.PreSessionCount); i++)//TODO:const of 5 { _ = Task.Run(this.ProvidePreSessionAsync); } _ = Task.Run(this.MaintainSessionsAsync); if (this.Client.RouterClientPort > 0) { _ = this.swrite.WriteAsync(new CommandMessage("SetOption", "RouterClientPort", this.Client.RouterClientPort.ToString()).Pack()); } byte[] readbuff = new byte[TcpMapService.defaultBufferSize]; while (this.IsStarted) { CommandMessage msg; var cts = new CancellationTokenSource(); _ = Task.Run(async delegate { if (await cts.Token.WaitForSignalSettedAsync(16000)) { return; } try { await this.swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack()); } catch (Exception x) { this.OnError(x); } }); try { msg = await CommandMessage.ReadFromStreamAsync(this.sread); } finally { cts.Cancel(); } if (msg == null) { TcpMapService.LogMessage("no message ? Connected:" + this.socket.Connected); return; } //this.LogMessage("TcpMapClientWorker get msg " + msg); switch (msg.Name) { case "StartSession": Task.Run(async delegate { try { await this.DoStartSessionAsync(msg); } catch (Exception x) { this.OnError(x); } }).ToString(); break; case "CloseSession": Task.Run(async delegate { try { await this.DoCloseSessionAsync(msg); } catch (Exception x) { this.OnError(x); } }).ToString(); break; case "CreateUDPNat": Task.Run(async delegate { try { await this.DoCreateUDPNatAsync(msg); } catch (Exception x) { this.OnError(x); } }).ToString(); break; case "_ping_": await this.swrite.WriteAsync(new CommandMessage("_ping_result_").Pack()); break; case "_ping_result_": break; default: this.LogMessage("Error: 4 Ignore message " + msg); break; } } } catch (SocketException) { //no log } catch (Exception x) { this.OnError(x); } if (this.IsStarted) { this.socket.CloseSocket();//logic failed.. againTimeout = 125; goto StartAgain; } } catch (Exception x) { this.OnError(x); } this.IsStarted = false; this.IsConnected = false; if (this.socket != null) { try { this.socket.CloseSocket(); } catch (Exception x) { this.OnError(x); } this.socket = null; } }
async Task WorkAsync() { IsStarted = true; IsConnected = false; //LogMessage("ClientSession WorkAsync start"); int connectedTimes = 0; try { int againTimeout = 125; StartAgain: _sock_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _sock_server.InitTcp(); _cts_connect = new CancellationTokenSource(); try { await _sock_server.ConnectAsync(Client.ServerHost, 6022); //LogMessage("connected to 6022"); } catch (Exception x) { OnError(x); _sock_server.CloseSocket(); _sock_server = null; _cts_connect = new CancellationTokenSource(); if (!IsStarted) { return; } if (againTimeout < 4) { againTimeout = againTimeout * 2; } if (await _cts_connect.Token.WaitForSignalSettedAsync(againTimeout)) { return; } goto StartAgain; } try { bool supportEncrypt = false; byte[] clientKeyIV; { CommandMessage connmsg = new CommandMessage(); connmsg.Name = "SessionConnect"; List <string> arglist = new List <string>(); arglist.Add(this.Client.License.Key); arglist.Add(this.Client.ServerPort.ToString()); byte[] encryptedKeyIV, sourceHash; Client.License.GenerateSecureKeyAndHash(out clientKeyIV, out encryptedKeyIV, out sourceHash); arglist.Add(Convert.ToBase64String(encryptedKeyIV)); arglist.Add(Convert.ToBase64String(sourceHash)); arglist.Add(supportEncrypt ? "1" : "0"); arglist.Add(SessionId); //sessionid at [5] connmsg.Args = arglist.ToArray(); await _sock_server.SendAsync(connmsg.Pack(), SocketFlags.None); //LogMessage("wait for conn msg"); connmsg = await CommandMessage.ReadFromSocketAsync(_sock_server); if (connmsg == null) { TcpMapService.LogMessage("no message ? Connected:" + _sock_server.Connected); return; } //LogMessage("connmsg : " + connmsg.Name + " : " + string.Join(",", connmsg.Args)); if (connmsg.Name != "ConnectOK") { IsStarted = false; //don't go until start it again. throw new Exception(connmsg.Name + " : " + string.Join(",", connmsg.Args)); } if (connmsg.Args[1] == "0") { supportEncrypt = false; } } IsConnected = true; connectedTimes++; //LogMessage("ConnectOK #" + connectedTimes); if (supportEncrypt) { Client.License.OverrideStream(_sock_server.CreateStream(), clientKeyIV, out _sread, out _swrite); } else { _sread = _swrite = _sock_server.CreateStream(); } if (string.IsNullOrEmpty(SessionId)) { //wait for Upgrade while (SessionId == null) { CommandMessage msg; var cts = new CancellationTokenSource(); _ = Task.Run(async delegate { if (await cts.Token.WaitForSignalSettedAsync(16000)) { return; } await _swrite.WriteAsync(new CommandMessage("_ping_", "forread").Pack()); }); try { msg = await CommandMessage.ReadFromStreamAsync(_sread); } finally { cts.Cancel(); } if (msg == null) { throw (new SocketException(995)); } switch (msg.Name) { case "UpgradeSession": try { _sock_local = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _sock_local.InitTcp(); await _sock_local.ConnectWithTimeoutAsync(Client.ClientHost, Client.ClientPort, 12000); } catch (Exception x) { TcpMapService.OnError(x); await _swrite.WriteAsync(new CommandMessage("UpgradeSessionResult", "Failed").Pack()); continue; } SessionId = msg.Args[0]; if (_cts_upgrade != null) { _cts_upgrade.Cancel(); } await _swrite.WriteAsync(new CommandMessage("UpgradeSessionResult", "OK").Pack()); break; case "_ping_": await _swrite.WriteAsync(new CommandMessage("_ping_result_").Pack()); break; case "_ping_result_": break; default: LogMessage("Error: 1 Ignore message " + msg); break; } } } await WorkAsync(_sock_local.CreateStream()); } catch (Exception x) { OnError(x); } } catch (SocketException) { } catch (Exception x) { OnError(x); } IsStarted = false; IsConnected = false; _sock_server?.CloseSocket(); _sock_local?.CloseSocket(); _workend = true; }