private void CheckForInactiveSockets(int probingIntervall) { Task.Run(async() => { while (true) { try { await Task.Delay(probingIntervall); var currentTime = DateTime.UtcNow; var oldConnections = new List <ClientSocket>(); foreach (var client in this.CurrentClients) { if ((currentTime - client.Value.LastTimeStamp).TotalMinutes >= 2) //5.5 { _ = client.Value.Socket.CloseAsync(WebSocketCloseStatus.PolicyViolation, "Closed for inactivity", CancellationToken.None); // Close it without waiting for it if (this.CurrentClients.TryRemove(client.Key, out _)) // ----> New Version { // Remove old DeviceRepresentation WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); } } } } catch (Exception e) { Console.WriteLine("Watcher Error:" + e.Message); } } }); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { this.PiplineSockets = new ConcurrentDictionary <WebSocket, WebSocket>(); this.Pipelines = new ConcurrentDictionary <Pipeline, Pipeline>(); this.WebAdapters = new List <IWebAdapterAble>(); this.CurrentClients = new ConcurrentDictionary <ClientSocket, ClientSocket>(); this.BrowserClients = new ConcurrentDictionary <WebSocket, WebSocket>(); this.rootPath = env.WebRootPath; WebfileFactory.IndexPath = Path.Combine(this.rootPath, "index.html"); WebfileFactory.ScriptPath = Path.Combine(this.rootPath, "script.js"); this.LoadAdapterAssemblies(); WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseDefaultFiles(); app.UseStaticFiles(); app.UseFileServer(enableDirectoryBrowsing: true); app.UseWebSockets(); // Only for Kestrel app.Map("/ws", builder => { builder.Use(async(context, next) => { if (context.WebSockets.IsWebSocketRequest) { var webSocket = await context.WebSockets.AcceptWebSocketAsync(); var client = new ClientSocket(webSocket, Guid.NewGuid().ToString().Replace('-', 'x')); this.CurrentClients.TryAdd(client, client);//.Add(client); ---> New Version await this.ClientDevice(client); // Device disconected -> remove and update ---------> New Version if (this.CurrentClients.TryRemove(client, out _)) { // Remove old DeviceRepresentation -> override old outdated index and script files WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); } return; } await next(); }); }); app.Map("/bs", builder => { builder.Use(async(context, next) => { if (context.WebSockets.IsWebSocketRequest) { var webSocket = await context.WebSockets.AcceptWebSocketAsync(); this.BrowserClients.TryAdd(webSocket, webSocket); //Task.Run( async () => //{ // await Task.Delay(5000); // await webSocket.CloseAsync(WebSocketCloseStatus.Empty,"ForcesClose",CancellationToken.None); // this.BrowserClients.TryTake(out webSocket); //}); await this.BrowserDevices(webSocket); // Device disconected -> remove and update this.BrowserClients.TryRemove(webSocket, out _); return; } await next(); }); }); app.Map("/ps", builder => { builder.Use(async(context, next) => { if (context.WebSockets.IsWebSocketRequest) { var webSocket = await context.WebSockets.AcceptWebSocketAsync(); this.PiplineSockets.TryAdd(webSocket, webSocket); await this.ListenPipelines(webSocket); // Device disconected -> remove and update this.PiplineSockets.TryRemove(webSocket, out _); return; } await next(); }); }); //Start watcher this.CheckForInactiveSockets(500); }
private async Task ListenPipelines(WebSocket webSocket) { byte[] buffer = new byte[1024 * 4]; WebSocketReceiveResult result; //foreach (var p in this.Pipelines) //{ // var message = $"add:{p.FromId}-->{p.ToId}"; // await webSocket.SendAsync(new ArraySegment<byte>(this.EncodeToByteArray(message), 0, message.Length), WebSocketMessageType.Text, true, CancellationToken.None); //} do { result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); var pipeObj = this.DecodeByteArray(buffer, result.Count).Split(";;"); var pipeParts = pipeObj[0].Split(":"); if (pipeParts.Length > 1) { var ids = pipeParts[1].Split("-->"); if (ids.Length > 1) { var tempD = new Dictionary <ClientSocket, ClientSocket>(this.CurrentClients); // ------> New Version // Find the correct pipeline if any exists if (tempD.Where(x => x.Value.UniqueID == ids[0] || x.Value.UniqueID == ids[1]).Count() == 2) { if (pipeParts[0] == "add") { var additionalParams = string.Empty; if (pipeObj.Length > 1) { additionalParams = pipeObj[1]; } var pipe = new Pipeline(ids[0], ids[1], additionalParams); this.Pipelines.TryAdd(pipe, pipe); WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); } if (pipeParts[0] == "delete") { Pipeline foundpipeline = null; foreach (var p in this.Pipelines) { if (p.Value.FromId == ids[0] && p.Value.ToId == ids[1]) { foundpipeline = p.Key; break; } } if (foundpipeline != null) { //// Inform everyone and yourself to delete the pipeline //foreach (var ps in this.PiplineSockets) //{ // await ps.SendAsync(new ArraySegment<byte>(this.EncodeToByteArray(pipeObj), 0, pipeObj.Length), WebSocketMessageType.Text, true, CancellationToken.None); //} this.Pipelines.TryRemove(foundpipeline, out _); // ----> New Version WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); } } } else { var errormsg = "error:No matching ids found"; await webSocket.SendAsync(new ArraySegment <byte>(this.EncodeToByteArray(errormsg), 0, errormsg.Length), WebSocketMessageType.Text, true, CancellationToken.None); } } } }while (!result.CloseStatus.HasValue); await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); }
//private void CheckForInactiveSockets(int duration, ClientSocket con) //{ // Task.Run(() => // { // while (true) // { // Task.Delay(duration); // var currentTime = DateTime.UtcNow; // var oldConnections = new List<ClientSocket>(); // if ((currentTime - con.LastTimeStamp).TotalMinutes > 5.5) // { // con.Socket.CloseAsync(WebSocketCloseStatus.PolicyViolation, "Closed for inactivity", CancellationToken.None); // this.CurrentClients.TryTake(out con); // // Remove old DeviceRepresentation // WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); // return; // } // } // }); //} private async Task ClientDevice(ClientSocket clientSocket) { byte[] buffer = new byte[1024 * 4]; var result = await clientSocket.Socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); var protoObj = new ProtocollObject(this.DecodeByteArray(buffer, result.Count)); // do only it is the reconnecting device //"identifier:" + identifier + ";adapter:"+adapter+";name:"+adapterName+";;reconnection:"+identifier+";"; try { var clientToReplace = this.CurrentClients .Where(client => client.Key.LastProtoObj != null && (client.Key.LastProtoObj.ParamObjects .Where(paramObj => paramObj.ParamName == "reconnection") .FirstOrDefault() != null)) .FirstOrDefault(); if (clientToReplace.Key != null) { string id = clientToReplace.Key.LastProtoObj.ParamObjects .Where(a => a.ParamName == "reconnection") .First().Value; // security issue if (protoObj.Identifier == id && protoObj.ParamObjects.Where(paramObj => paramObj.ParamName == "reconnection").FirstOrDefault() != null) { clientSocket.UniqueID = id; } //if (protoObj.ParamObjects.Where(paramObj => paramObj.ParamName == "reconnection").FirstOrDefault() != null) //{ //clientSocket.UniqueID = id; //} try { // ClientSocket clientToRemove = this.CurrentClients.Where(a => a.LastProtoObj.ParamObjects.Where(a => a.ParamName == "deleteConn").FirstOrDefault() != null).FirstOrDefault(); //this.CurrentClients = new ConcurrentBag<ClientSocket>(this.CurrentClients.Except(new[] { clientToReplace })); this.CurrentClients.TryRemove(clientToReplace.Key, out _); WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); //this.CheckForInactiveSockets(500); redundand await clientToReplace.Key.Socket.CloseAsync(WebSocketCloseStatus.PolicyViolation, "Closed for inactivity", CancellationToken.None); } catch { // } } } catch (Exception e) { // } // Set serverside Identifier protoObj.Identifier = clientSocket.UniqueID; clientSocket.Name = protoObj.Name; clientSocket.LastProtoObj = protoObj; IWebAdapterAble foundAdapter = null; foreach (var adapt in this.WebAdapters) { if (adapt.AdapterName == protoObj.Adapter) { foundAdapter = adapt; break; } } if (foundAdapter == null) { clientSocket.Socket.CloseAsync(WebSocketCloseStatus.ProtocolError, "No matching adapter found", CancellationToken.None).Wait(5000); return; } else { clientSocket.Adapter = foundAdapter; } WebfileFactory.GenerateFiles(this.CurrentClients, this.Pipelines); var message = protoObj.BuildProtocollMessage(); // Inform device about its number await clientSocket.Socket.SendAsync(new ArraySegment <byte>(this.EncodeToByteArray(message), 0, message.Length), result.MessageType, result.EndOfMessage, CancellationToken.None); while (!result.CloseStatus.HasValue) { result = await clientSocket.Socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); // Refresh last recieved message clientSocket.LastTimeStamp = DateTime.UtcNow; //this.CheckForInactiveSockets(5000, clientSocket); Console.WriteLine(this.DecodeByteArray(buffer, result.Count) + "++++++++++++++++++++++++++++++++++++++++++++"); if (clientSocket.PriorityProtoObj == null) { // Create new ProtocollObject from the clients message protoObj = new ProtocollObject(this.DecodeByteArray(buffer, result.Count)); // Set serverside Identifier protoObj.Identifier = clientSocket.UniqueID; clientSocket.LastProtoObj = protoObj; message = protoObj.BuildProtocollMessage().Split(";;")[0] + ";;"; //// should stay before so the client is not waiting await clientSocket.Socket.SendAsync(new ArraySegment <byte>(this.EncodeToByteArray(message), 0, message.Length), result.MessageType, result.EndOfMessage, CancellationToken.None); // Update value of webpage and inform pipeline targets await this.DistributeToBrowserClients(protoObj);//.ConfigureAwait(true); //false await this.UsePipelines(protoObj); } else { message = clientSocket.PriorityProtoObj.BuildProtocollMessage(); await clientSocket.Socket.SendAsync(new ArraySegment <byte>(this.EncodeToByteArray(message), 0, message.Length), result.MessageType, result.EndOfMessage, CancellationToken.None); clientSocket.PriorityProtoObj = null; } //await clientSocket.Socket.SendAsync(new ArraySegment<byte>(this.EncodeToByteArray(message), 0, message.Length), result.MessageType, result.EndOfMessage, CancellationToken.None); } await clientSocket.Socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); }