Advertisement
Guest User

Untitled

a guest
Nov 17th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.73 KB | None | 0 0
  1. namespace Shoplogix.Server.ScreenManagement
  2. {
  3.     using System;
  4.     using System.Linq;
  5.     using System.Text;
  6.     using Shoplogix.Streaming;
  7.     using Newtonsoft.Json;
  8.     using Common.Logging;
  9.     using Services;
  10.     using Shoplogix.Server.Configuration;
  11.     using System.Diagnostics;
  12.     using System.Collections.Concurrent;
  13.  
  14.  
  15.     class ScreenSocketModule : ISocketModule
  16.     {
  17.         private const string portal_protocol = "portal";
  18.         private const string client_protocol = "client";
  19.         private const string identify_protocol = "identify";
  20.         private const string delete_protocol = "delete";
  21.         private const string closing_protocol = "closing";
  22.         private const string error_protocol = "error";
  23.         private const string url_protocol = "url";
  24.         private const string ping_protocol = "ping";
  25.         private const string heartbeat_protocol = "stayinalive";
  26.         private const string quick_description_protocol = "quickdescription";
  27.  
  28.         private IUserProvider user;
  29.  
  30.         private ILog logger;
  31.  
  32.         private IRoleProvider roleProvider;
  33.  
  34.         private IConfigManager configManager;
  35.  
  36.         private IAccessRuleManager ruleManager;
  37.  
  38.         ConcurrentDictionary<SocketClient, string> unclassified = new ConcurrentDictionary<SocketClient, string>();
  39.         ScreenPortals portals = null;
  40.         ScreenClients clients = null;
  41.  
  42.         public ScreenSocketModule(IUserProvider user, ILog logger, IRoleProvider roleProvider, IConfigManager configManager, IAccessRuleManager ruleManager)
  43.         {
  44.             this.user = user;
  45.             this.logger = logger;
  46.             this.roleProvider = roleProvider;
  47.             this.configManager = configManager;
  48.             this.ruleManager = ruleManager;
  49.             portals = new ScreenPortals();
  50.             clients = new ScreenClients(ruleManager, roleProvider, configManager, logger);
  51.  
  52.             JsonConvert.DefaultSettings = () => ApiConstants.JsonSettings;
  53.         }
  54.  
  55.         public bool Accept(SocketClient client)
  56.         {
  57.             try
  58.             {
  59.                 if (!client.Context.Path.Contains("screenmanagement.axd"))
  60.                 {
  61.                     return false;
  62.                 }
  63.  
  64.                 if (clients.Update == null)
  65.                 {
  66.                     clients.Update += clients_CollectionChanged;
  67.                 }
  68.  
  69.                 unclassified[client] = user.CurrentUser;
  70.  
  71.                 client.Received += Client_Received;
  72.  
  73.                 return true;
  74.             }
  75.             catch (Exception e)
  76.             {
  77.                 this.logger.Error(e.Message);
  78.                 return false;
  79.             }
  80.         }
  81.  
  82.         private void Client_Received(object sender, SocketReceiveEventArgs e)
  83.         {
  84.             string message = Encoding.Default.GetString(e.Message).Replace("\0", string.Empty);
  85.             var client = e.Client;
  86.             if (unclassified.ContainsKey(client))
  87.             {
  88.                 if (message.StartsWith(portal_protocol))
  89.                 {
  90.                     message = message.RemovePrefix(portal_protocol);
  91.                     //if new portal
  92.                     if (message.StartsWith(ping_protocol))
  93.                     {
  94.                         NewPortal(client, unclassified[client]);
  95.                     }
  96.                     else
  97.                     {
  98.                         logger.Info("Invalid string from websocket");
  99.                         client.Dispose(); //should also close the connection
  100.                     }
  101.                 }
  102.                 else if (message.StartsWith(client_protocol))
  103.                 {
  104.                     message = message.RemovePrefix(client_protocol);
  105.                     if (message.StartsWith(ping_protocol))
  106.                     {
  107.                         message = message.RemovePrefix(ping_protocol);
  108.                         if (message.Length < 1)
  109.                         {
  110.                             NewClient(client, unclassified[client]);
  111.                         }
  112.                         else if (message.StartsWith(quick_description_protocol))
  113.                         {
  114.                             message = message.RemovePrefix(quick_description_protocol);
  115.                             NewClient(client, unclassified[client], message);
  116.                         }
  117.                         else
  118.                         {
  119.                             LoadClient(client, unclassified[client] ,message);
  120.                         }
  121.                     }
  122.                     else
  123.                     {
  124.                         logger.Info("Invalid string from websocket");
  125.                         client.Dispose(); //should also close the connection
  126.                     }
  127.                 }
  128.  
  129.                 var removedMessage = (string)null;
  130.                 if (!unclassified.TryRemove(client, out removedMessage)) this.logger.Warn("Failed to remove client.");
  131.  
  132.             }
  133.  
  134.             if (message.StartsWith(portal_protocol))
  135.             {
  136.                 message = message.RemovePrefix(portal_protocol);
  137.                 var nPortal = portals.FindByContext(client.Context, user.CurrentUser);
  138.                 HandlePortal(nPortal, message);
  139.             }
  140.  
  141.             if (message.StartsWith(client_protocol))
  142.             {
  143.                 message = message.RemovePrefix(client_protocol);
  144.                 var nClient = clients.FindByContext(client.Context, user.CurrentUser);
  145.                 HandleClient(nClient, message);
  146.             }
  147.         }
  148.  
  149.         private void HandlePortal(ScreenPortal portal, string message)
  150.         {
  151.             if (portal != null)
  152.             {
  153.                 //identify
  154.                 if (message.StartsWith(identify_protocol))
  155.                 {
  156.                     message = message.RemovePrefix(identify_protocol);
  157.                     var clientSocket = clients.FindByID(message);
  158.                     if (clientSocket != null)
  159.                     {
  160.                         clientSocket.Send(identify_protocol);
  161.                         logger.Debug("Sending: " + identify_protocol);
  162.                     }
  163.                     else
  164.                     {
  165.                         logger.Error("Client ID not found while trying to identify");
  166.                         string errorMessage = error_protocol + "Client ID not found while trying to identify";
  167.                         portal.Socket.Send(errorMessage);
  168.                         logger.Debug("Sending: " + errorMessage);
  169.                     }
  170.                 }
  171.                 //delete
  172.                 else if (message.StartsWith(delete_protocol))
  173.                 {
  174.                     message = message.RemovePrefix(delete_protocol);
  175.                     var clientSocket = clients.FindByID(message);
  176.                     if (clientSocket != null)
  177.                     {
  178.                         var screen = clients.FindByKey(clientSocket.Context.SecWebSocketKey);
  179.                         clientSocket.Dispose();
  180.                         clients.Delete(screen);
  181.                         clientSocket.Send(delete_protocol);
  182.                         logger.Debug("Deleting: " + screen.Id);
  183.                     }
  184.                     else
  185.                     {
  186.                         try
  187.                         {
  188.                             var configToDelete = FindMatchingClient(message);
  189.  
  190.                             //Clients should always contain the key.
  191.                             if (clients.ContainsKey(configToDelete))
  192.                             {
  193.                                 logger.Debug("Deleting: " + message);
  194.                                 clients.Delete(configToDelete);
  195.                                 clients.RemoveFromConfig(new Guid(message), portal.Account);
  196.                                 portal.Socket.Send(delete_protocol + message);
  197.                             }
  198.                             else
  199.                             {
  200.                                 //ID requested is not found in list of clients. Try to aesthetically delete it from the list anyways
  201.                                 logger.Error("Requested ID not found in list of client IDs");
  202.                                 portal.Socket.Send(delete_protocol + message);
  203.                             }
  204.                         }
  205.                         catch (Exception)
  206.                         {
  207.                             logger.Error("Client ID not found while trying to delete");
  208.                             string errorMessage = error_protocol + "Client ID not found while trying to delete";
  209.                             portal.Socket.Send(errorMessage);
  210.                             logger.Debug("Sending: " + errorMessage);
  211.                         }
  212.                     }
  213.                 }
  214.                 //update
  215.                 else
  216.                 {
  217.                     var screen = JsonConvert.DeserializeObject<ScreenConfig>(message);
  218.                     var existingScreen = clients.Keys.FirstOrDefault(k => k.Id == screen.Id);
  219.                     if (existingScreen != null)
  220.                     {
  221.                         var client = clients.UpdateScreenSettings(existingScreen, screen);
  222.                         logger.Info("Updated client");
  223.                         var rowMessage = SerializeScreen(screen);
  224.                         client.Send(rowMessage);
  225.                         logger.Debug("Sending: " + rowMessage);
  226.  
  227.                         portal.Socket.Send(rowMessage);
  228.                         logger.Debug("Sending: " + rowMessage);
  229.                     }
  230.                     else
  231.                     {
  232.                         logger.Error("Client ID not found while trying to update");
  233.                         string errorMessage = error_protocol + "Client ID not found while trying to update";
  234.                         portal.Socket.Send(errorMessage);
  235.                         logger.Debug("Sending: " + errorMessage);
  236.                     }
  237.                 }
  238.             }
  239.             else
  240.             {
  241.                 logger.Error("Portal was null, either the list was empty or the connection doesn't exist");
  242.             }
  243.         }
  244.  
  245.         private void NewPortal(SocketClient client, string account)
  246.         {
  247.             var areas = this.configManager.CurrentConfig.RootArea.Areas
  248.                 .Where(a => ruleManager.CurrentRules.CanRead(roleProvider, account, a) && a.Screens.Any());
  249.  
  250.             var portal = new ScreenPortal(Guid.NewGuid(), client, account);
  251.             portals.Add(portal);
  252.             if (clients.Any())
  253.             {
  254.                 foreach (var screen in areas.SelectMany(a => a.Screens))
  255.                 {
  256.                     if (!clients.ContainsKey(screen)) continue;
  257.  
  258.                     var rowMessage = SerializeScreen(screen);
  259.                     portal.Socket.Send(rowMessage);
  260.                     logger.Debug("Sending: " + rowMessage);
  261.                 }
  262.             }
  263.  
  264.             foreach (var screen in clients)
  265.             {
  266.                 if (screen.Value != null && !screen.Value.Closed)
  267.                 {
  268.                     screen.Key.Online = true;
  269.                 }
  270.                 else
  271.                 {
  272.                     screen.Key.Online = false;
  273.                 }
  274.                 var rowMessage = SerializeScreen(screen.Key);
  275.                 portal.Socket.Send(rowMessage);
  276.                 logger.Debug("Sending: " + rowMessage);
  277.             }
  278.         }
  279.  
  280.         private string SerializeScreen(ScreenConfig screen)
  281.         {
  282.             return "row" + JsonConvert.SerializeObject(screen);
  283.         }
  284.  
  285.         private void HandleClient(ScreenConfig screen, string message)
  286.         {
  287.             if (screen != null)
  288.             {
  289.                 if (message.StartsWith(url_protocol))
  290.                 {
  291.                     var next = screen.Next();
  292.                     string json = JsonConvert.SerializeObject(next);
  293.                     clients[screen].Send(url_protocol + json);
  294.                     logger.Debug("Sending: " + url_protocol + json);
  295.                 }
  296.                 else if (message.StartsWith(heartbeat_protocol))
  297.                 {
  298.                     clients[screen].Send(heartbeat_protocol);
  299.                     logger.Debug("Heartbeat");
  300.                 }
  301.             }
  302.             else
  303.             {
  304.                 logger.Error("Client was null, either the list was empty or the connection doesn't exist");
  305.             }
  306.         }
  307.  
  308.         private void LoadClient(SocketClient clientConnection, string account, string id)
  309.         {
  310.             Debug.WriteLine("LoadClient");
  311.             var screen = clients.Keys.FirstOrDefault(k => Text.Equal(k.Id.ToString(), id));
  312.             if (screen != null)
  313.             {
  314.                 screen.Online = true;
  315.                 clients.UpdateConnection(screen, clientConnection);
  316.                 string json = SerializeScreen(screen);
  317.                 string jsonForClient = json.Replace("id:", "newid:");
  318.                 clientConnection.Send(jsonForClient);
  319.                 portals.Broadcast(json, screen.Account);
  320.             }
  321.             else
  322.             {
  323.                 logger.Warn($"Client ID: {id} not found.");
  324.                 //clientConnection.Send(error_protocol + $"Client ID: {id} not found.");
  325.                 //clientConnection.Dispose();
  326.                 logger.Info("Attempting to create new client");
  327.                 NewClient(clientConnection, account, id);
  328.  
  329.             }
  330.         }
  331.  
  332.         private void NewClient(SocketClient client, string account, string description = "")
  333.         {
  334.             var screen = clients.AddNew(account, description, client);
  335.             string json = SerializeScreen(screen);
  336.             string jsonForClient = json.Replace("id:", "newid:");
  337.             client.Send(jsonForClient);
  338.             logger.Debug("Sending: " + jsonForClient);
  339.             logger.Info("New client");
  340.         }
  341.  
  342.         void clients_CollectionChanged(object send, ScreenListChangedEventArgs e)
  343.         {
  344.             if (e.Action == SocketListAction.Add || e.Action == SocketListAction.Update)
  345.             {
  346.                 string json = SerializeScreen(e.Screen);
  347.                 portals.Broadcast(json, e.Screen.Account);
  348.             }
  349.             if (e.Action == SocketListAction.Remove)
  350.             {
  351.                 portals.Broadcast(delete_protocol + e.Screen.Id.ToString(), e.Screen.Account);
  352.             }
  353.         }
  354.         //Searches for client with id of "msg", and returns that client's ScreenConfig
  355.         private ScreenConfig FindMatchingClient(string msg)
  356.         {
  357.             foreach (var client in clients)
  358.             {
  359.                 var idAsString = client.Key.Id.ToString();
  360.                 if (msg == idAsString)
  361.                 {
  362.                     return client.Key;
  363.                 }
  364.             }
  365.             return null;
  366.         }
  367.     }
  368. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement