public async Task ProcessRecControl(TcpCSSocketControl control) { byte newControl = 0; bool close = false; if (!Accepted) { if (control.CheckFlag(TcpCSSocketControl.AcceptConnection)) { Accepted = true; newControl |= TcpCSSocketControl.Ready; } else if (control.CheckFlag(TcpCSSocketControl.RefuseConnection)) { newControl |= TcpCSSocketControl.Close; close = true; } } if (control.CheckFlag(TcpCSSocketControl.Close)) { newControl |= TcpCSSocketControl.Close; close = true; } await Connection.Stream.WriteAsync((new TcpCSSocketControl(SocketId, newControl)).Build()); if (close) { Connections.Remove(IdToString(SocketId)); } }
/// <summary> /// Initiates the connection to the app /// </summary> /// <returns>An async Task</returns> /// <exception cref="Exception">Thrown if the connection is refused</exception> public async Task Connect() { if (SocketId != null) { return; } ConnectCompletionSource = new TaskCompletionSource <bool>(); uint nonce = Packet.WatchNonce(async pk => { await Task.Run(() => { TcpCSSocketControl control = new TcpCSSocketControl(pk); SocketId = control.SocketId; EP.Connections.Add(IdToString(control.SocketId), this); Requestor = true; Stream = new NRStream(this); if (control.CheckFlag(TcpCSSocketControl.Close)) { ConnectCompletionSource.SetResult(false); } }); }); EP.TransmitRaw(new TcpCOpenSocket(InstanceId, nonce)); bool success = await ConnectCompletionSource.Task; if (!success) { await Close(false); throw new Exception("Connect to distant end was refused."); } }
public async Task ProcessReqControl(TcpCSSocketControl control) { byte newControl = 0; if (control.CheckFlag(TcpCSSocketControl.Close)) { newControl |= TcpCSSocketControl.Close; Connections.Remove(IdToString(SocketId)); } await App.Connection.Stream.WriteAsync((new TcpCSSocketControl(SocketId, newControl)).Build()); }
/// <summary> /// Refuses the connection /// </summary> public async Task Refuse() { if ((Requestor && !Loopback) || Open) { return; } TcpCSSocketControl control = new TcpCSSocketControl(SocketId, TcpCSSocketControl.RefuseConnection); EP.TCPConnection.Stream.Write(control.Build()); await Close(false); }
public static async Task StandardSocketControlHandler(Packet packet) { var pa = new TcpCSSocketControl(packet); var ep = ((EntryPoint)packet.Connection.Ref); Log.Debug("Socket Control Detail for socket {Socket}: [{Flags}] {Extra}", pa.SocketId, pa.ReadableFlags, pa.InstanceId); AppConnection x = null; ep.Connections.TryGetValue(AppConnection.IdToString(pa.SocketId), out x); StoredApp app = null; if (pa.CheckFlag(TcpCSSocketControl.OpenRequest)) { if (x == null) { x = new AppConnection(pa.InstanceId, ep); x.SocketId = pa.SocketId; } else { x.Loopback = true; Log.Debug("Connection {Sid} switched to loopback mode", pa.SocketId); } app = ep._registeredApps.FirstOrDefault(e => e.InstanceId.SequenceEqual(x.InstanceId)); ep.Connections.Add(AppConnection.IdToString(pa.SocketId), x); await app.Callback(x); } if (x == null) { return; } if (pa.CheckFlag(TcpCSSocketControl.Ready)) { x.Open = true; x.ConnectCompletionSource.SetResult(true); } if (pa.CheckFlag(TcpCSSocketControl.Close)) { if (!x.Open) { x.ConnectCompletionSource.SetResult(false); } _ = Task.Run(async() => { await Task.Delay(500); await x.Close(); }); } }
public async Task ProcessControl(Packet packet) { TcpCSSocketControl control = new TcpCSSocketControl(packet); if (App.Connection.Socket == packet.Connection.Socket) { await ProcessRecControl(control); } else { await ProcessReqControl(control); } }
/// <summary> /// Accepts the connection /// </summary> public async Task Accept() { await Task.Run(() => { if ((Requestor && !Loopback) || Open) { return; } Stream = new NRStream(this); TcpCSSocketControl control = new TcpCSSocketControl(SocketId, TcpCSSocketControl.AcceptConnection); EP.TCPConnection.Stream.Write(control.Build()); Open = true; }); }
public static async Task OpenSocket(Packet packet) { var ap = new TcpCOpenSocket(packet); var app = AppManager.PublishedApps.FirstOrDefault(x => x.InstanceId.SequenceEqual(ap.InstanceId)); var reply = new byte[0]; if (app == null) { reply = new TcpCSSocketControl(new byte[10], TcpCSSocketControl.OpenAck | TcpCSSocketControl.Close, packet.Nonce).Build(); } else { AppConnection connection = new AppConnection(packet.Connection, app); await connection.SendInitialState(packet); } await packet.Connection.Stream.WriteAsync(reply); }
/// <summary> /// Closes the connection /// </summary> /// <param name="sendPack">Whether to send the payload. Usually this is true.</param> public async Task Close(bool sendPack = true) { await Task.Run(() => { if (!Open) { return; } Open = false; if (sendPack) { TcpCSSocketControl control = new TcpCSSocketControl(SocketId, TcpCSSocketControl.Close); EP.TransmitRaw(control); } if (Stream != null && Stream.IsOpen) { Stream.Close(); } EP.Connections.Remove(IdToString(SocketId)); }); }
public static async Task ConnectionControl(Packet packet) { TcpCSSocketControl control = new TcpCSSocketControl(packet); var conn = AppConnection.Connections[AppConnection.IdToString(control.SocketId)]; await conn.ProcessControl(packet); }