The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IRCClientHub.cs 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using Microsoft.AspNet.SignalR;
  2. using Microsoft.AspNet.SignalR.Hubs;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Web;
  7. using Teknik.Attributes;
  8. using Teknik.SignalR;
  9. using System.Threading.Tasks;
  10. using System.Timers;
  11. using Teknik.Areas.Users.Utility;
  12. using Teknik.Areas.Users.Models;
  13. using Teknik.Models;
  14. using Teknik.Configuration;
  15. using Teknik.Utilities;
  16. namespace Teknik.Hubs
  17. {
  18. [HubName("ircClient")]
  19. public class IRCClientHub : Hub
  20. {
  21. private static Dictionary<string, string> _Connections = new Dictionary<string, string>();
  22. private static Dictionary<string, Tuple<IRCClient, Timer>> _Clients = new Dictionary<string, Tuple<IRCClient, Timer>>();
  23. private const int _DisconnectTimeout = 30; // Timeout to disconnect from IRC server after client disconnects from hub (Seconds)
  24. public IRCClientHub()
  25. {
  26. }
  27. public override Task OnDisconnected(bool stopCalled)
  28. {
  29. // Get the username for this connection
  30. string username = string.Empty;
  31. if (Context != null)
  32. {
  33. if (_Connections.ContainsKey(Context.ConnectionId))
  34. {
  35. // Get the username
  36. username = _Connections[Context.ConnectionId];
  37. // Remove this connection from the list
  38. _Connections.Remove(Context.ConnectionId);
  39. }
  40. }
  41. // Start disconnect timer for this user
  42. if (_Clients.ContainsKey(username))
  43. {
  44. // Start disconnect timer
  45. _Clients[username].Item2.Start();
  46. }
  47. return base.OnDisconnected(stopCalled);
  48. }
  49. public string Connect()
  50. {
  51. // Create guest username
  52. string username = "Guest_" + StringHelper.RandomString(6, "0123456789");
  53. Connect(username, string.Empty);
  54. return username;
  55. }
  56. public bool Connect(string username, string password)
  57. {
  58. bool success = true;
  59. // If the password is supplied, verify the password
  60. if (!string.IsNullOrEmpty(password))
  61. {
  62. TeknikEntities db = new TeknikEntities();
  63. User user = UserHelper.GetUser(db, username);
  64. if (user != null)
  65. {
  66. Config config = Config.Load();
  67. success = UserHelper.UserPasswordCorrect(db, config, user, password);
  68. }
  69. else
  70. {
  71. success = false;
  72. }
  73. }
  74. if (success)
  75. {
  76. // Update this connection with the username associated we want to associate with it
  77. if (Context != null)
  78. {
  79. if (!_Connections.ContainsKey(Context.ConnectionId))
  80. {
  81. _Connections.Add(Context.ConnectionId, string.Empty);
  82. }
  83. _Connections[Context.ConnectionId] = username;
  84. }
  85. // Add the client for this user if it doesn't exist
  86. if (!_Clients.ContainsKey(username))
  87. {
  88. // Client doesn't exist, so create it
  89. Timer disconnectTimer = new Timer(_DisconnectTimeout * 1000);
  90. disconnectTimer.Elapsed += (sender, e) => DisconnectTimer_Elapsed(sender, e, username);
  91. // Add the new connection to the main list
  92. _Clients.Add(username, new Tuple<IRCClient, Timer>(new IRCClient(Clients.Caller), disconnectTimer));
  93. }
  94. // Stop the disconnect timer because we have reconnected
  95. _Clients[username].Item2.Stop();
  96. // Reassociate this connection with the user
  97. _Clients[username].Item1.CallerContext = Clients.Caller;
  98. // Connect
  99. _Clients[username].Item1.Connect(username, password);
  100. }
  101. return success;
  102. }
  103. public void SendMessage(string location, string message)
  104. {
  105. string username = GetConnectionUser();
  106. if (_Clients.ContainsKey(username))
  107. {
  108. _Clients[username].Item1.SendMessage(location, message);
  109. }
  110. }
  111. public void SendRawMessage(string message)
  112. {
  113. string username = GetConnectionUser();
  114. if (_Clients.ContainsKey(username))
  115. {
  116. _Clients[username].Item1.SendRawMessage(message);
  117. }
  118. }
  119. private void DisconnectTimer_Elapsed(object sender, ElapsedEventArgs e, string username)
  120. {
  121. if (_Clients.ContainsKey(username))
  122. {
  123. // Disconnect from the IRC session
  124. _Clients[username].Item1.Disconnect();
  125. // Remove the irc client
  126. _Clients.Remove(username);
  127. }
  128. }
  129. private string GetConnectionUser()
  130. {
  131. if (Context != null)
  132. {
  133. if (_Connections.ContainsKey(Context.ConnectionId))
  134. {
  135. return _Connections[Context.ConnectionId];
  136. }
  137. }
  138. return string.Empty;
  139. }
  140. }
  141. }