PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/source/samples/ObviousCode.Interlace.BitTunnel/ObviousCode.Interlace.BitTunnelServer/BitTunnelServerProtocolFactory.cs

https://bitbucket.org/VahidN/interlace
C# | 196 lines | 147 code | 34 blank | 15 comment | 17 complexity | f8eee1dbfcc4bf5f4276223c88789691 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Interlace.ReactorCore;
  6. using ObviousCode.Interlace.BitTunnelLibrary.Events;
  7. using ObviousCode.Interlace.BitTunnelLibrary.Protocols;
  8. using ObviousCode.Interlace.BitTunnelLibrary.File;
  9. using ObviousCode.Interlace.BitTunnelLibrary.Interfaces;
  10. using System.Diagnostics;
  11. using ObviousCode.Interlace.BitTunnelLibrary.Messages;
  12. using ObviousCode.Interlace.BitTunnelLibrary.Messages.Headers;
  13. using System.Collections;
  14. using ObviousCode.Interlace.BitTunnelLibrary;
  15. namespace ObviousCode.Interlace.BitTunnelServer
  16. {
  17. public class BitTunnelServerProtocolFactory : BitTunnelProtocolFactory
  18. {
  19. public event EventHandler<IdentificationEventArgs> ClientConnected;
  20. public event EventHandler<IdentificationEventArgs> ClientIdentified;
  21. public event EventHandler<FileListModificationEventArgs> AvailableFilesUpdated;
  22. public event EventHandler ConnectionTerminated;
  23. BitTunnelServerService _service;
  24. public BitTunnelServerProtocolFactory(BitTunnelServerService service, string serverName) : base(service.Settings)
  25. {
  26. ServerId = Guid.NewGuid().ToString();
  27. ServerName = serverName;
  28. _service = service;
  29. }
  30. #region IProtocolFactory Members
  31. protected override BitTunnelProtocol CreateProtocol()
  32. {
  33. BitTunnelServerProtocol protocol = new BitTunnelServerProtocol(this);
  34. protocol.ClientConnected += new EventHandler<IdentificationEventArgs>(protocol_ClientConnected);
  35. protocol.LostConnection +=new EventHandler(protocol_LostConnection);
  36. protocol.ClientIdentified += new EventHandler<IdentificationEventArgs>(protocol_ClientIdentified);
  37. protocol.AvailableFilesUpdated += new EventHandler<FileListModificationEventArgs>(protocol_AvailableFilesUpdated);
  38. return protocol;
  39. }
  40. void protocol_AvailableFilesUpdated(object sender, FileListModificationEventArgs e)
  41. {
  42. if (AvailableFilesUpdated != null)
  43. {
  44. AvailableFilesUpdated(sender, e);
  45. }
  46. }
  47. void protocol_ClientIdentified(object sender, IdentificationEventArgs e)
  48. {
  49. if (ClientIdentified != null)
  50. {
  51. ClientIdentified(sender, e);
  52. }
  53. }
  54. void protocol_ClientConnected(object sender, IdentificationEventArgs e)
  55. {
  56. if (ClientConnected != null)
  57. {
  58. ClientConnected(sender, e);
  59. }
  60. }
  61. void protocol_LostConnection(object sender, EventArgs e)
  62. {
  63. ProtocolList.Remove(sender as BitTunnelProtocol);
  64. if (ConnectionTerminated!= null)
  65. {
  66. ConnectionTerminated(sender, e);
  67. }
  68. }
  69. public override void StartedConnecting()
  70. {
  71. Debug.WriteLine("Connecting ... - Should handle with NLog");
  72. }
  73. #endregion
  74. //LINQify
  75. internal IList<FileDescriptor> CurrentlyAvailableFiles
  76. {
  77. get
  78. {
  79. List<FileDescriptor> files = new List<FileDescriptor>();
  80. foreach (BitTunnelServerProtocol protocol in ProtocolList)
  81. {
  82. files.AddRange(protocol.Files.GetCurrentUniqueFileList());
  83. }
  84. return files;
  85. }
  86. }
  87. public override void OnConnectionFailed(Exception e)
  88. {
  89. }
  90. public override void OnMessageReceived(IMessage message)
  91. {
  92. }
  93. public int ConnectionCount
  94. {
  95. get
  96. {
  97. return ProtocolList.Count;
  98. }
  99. }
  100. internal string ServerName { get; private set; }
  101. internal string ServerId { get; private set; }
  102. internal void Broadcast(IMessage message)
  103. {
  104. BitTunnelServerProtocol[] asNow = new BitTunnelServerProtocol[ProtocolList.Count];
  105. ProtocolList.CopyTo(asNow);
  106. for (int i = 0; i < asNow.Length; i++)
  107. {
  108. asNow[i].SendMessage(message);
  109. }
  110. }
  111. //Send modifications where they appeared to have been valid
  112. //i.e Remove has fully removed all instances, or New where file is available on a client.
  113. //Functionality is, therefore, subtlety different for
  114. //
  115. // * Remove (will be used in the message ONLY when all files are removed) and
  116. // * New (will be added in the message whilst the uniquely hashed file is available each time an instance is added).
  117. //
  118. //As multiple of the same file (in different locations on the client) can be added at once,
  119. //it is not so easy to differentiate a 'first addition' of a file to only use those here as
  120. //
  121. //Currently up to clients as to whether to store the added files (with the limitToUniquelyHashedFilesOnly
  122. //flag on the FileDescriptorLookup).
  123. //
  124. //Sure I can come up with a nicer solution, but, until then, this is functionally accurate
  125. internal void BroadcastFileListModifications(List<FileModificationDescriptor> list)
  126. {
  127. if (ProtocolList.Count == 0) return;
  128. List<FileDescriptor> availableFiles = CurrentlyAvailableFiles as List<FileDescriptor>;
  129. using (FileModificationMessage message = new FileModificationMessage())
  130. {
  131. foreach(FileModificationDescriptor modification in list)
  132. {
  133. bool available = availableFiles.Exists(f => f.Hash == modification.Hash);
  134. if (
  135. (modification.Mode == FileModificationMode.New && available) ||
  136. (modification.Mode == FileModificationMode.Remove && !available) ||
  137. (modification.Mode == FileModificationMode.Renamed)
  138. )
  139. {
  140. ProtocolList[0].AddValueToMessage(message, modification);
  141. }
  142. }
  143. Broadcast(message);
  144. }
  145. }
  146. internal IList<BitTunnelServerProtocol> Protocols
  147. {
  148. get
  149. {
  150. return new List<BitTunnelServerProtocol>(ProtocolList.Cast<BitTunnelServerProtocol>());
  151. }
  152. }
  153. internal void RequestFile(FileDescriptor fileDescriptor, long chunkIndex, Action<FileDescriptor, FileRequestMode> sendResponseCallback, Action<FileDescriptor, FileChunkMessage> sendChunkCallback)
  154. {
  155. _service.RequestFile(fileDescriptor, chunkIndex, sendResponseCallback, sendChunkCallback);
  156. }
  157. internal void HandleFileChunk(FileChunkMessage message)
  158. {
  159. _service.FileChunkReceived(message);
  160. }
  161. }
  162. }