/// <summary> /// /// Start server loop that provide server pipe. /// </summary> /// <param name="guid">Id signed to connection.</param> /// <param name="pipeName">Name of the pipe that will be started.</param> /// <param name="securityLevel">Pipes security levels that will be applied to pipe.</param> /// <param name="getMessageHanler">Handler that generate brodcasting message for every connected client.</param> public static void ServerLoop( string guid, string pipeName, Security.SecurityLevel securityLevel, MessageHandeler getMessageHanler) { // Start loop. ServerAPI.ServerLoop <BroadcastTransmissionController>( guid, Handlers.DNS.BroadcastAsync, pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough, securityLevel, // Initialise broadcasting delegate. (BaseServerTransmissionController tc) => { if (tc is BroadcastTransmissionController bstc) { bstc.GetMessage = getMessageHanler; } else { // Stop server tc.SetStoped(); // Log error Console.WriteLine("SERVER ERROR (BSS_TC 10): Created controler can't be casted to BroadcastingServerTransmissionController"); } } ); }
/// <summary> /// Start server loop that provide server pipe. /// </summary> /// <param name="guid">Id signed to connection. Will generated authomaticly and returned to </param> /// <param name="pipeName">Name of the pipe that will be started.</param> /// <param name="securityLevel">Pipes security levels that will be applied to pipe.</param> /// <param name="getMessageHanler">Handler that generate brodcasting message for every connected client.</param> public static void ServerLoop( out string guid, string pipeName, Security.SecurityLevel securityLevel, MessageHandeler getMessageHanler) { // Generate GUID. guid = (System.Threading.Thread.CurrentThread.Name + "\\" + pipeName).GetHashCode().ToString(); // Start loop. ServerLoop(guid, pipeName, securityLevel, getMessageHanler); }
/// <summary> /// Provides a base server loop that controls a pipe. /// Has ability to full control all level of networking handlers. /// </summary> /// <param name="guid">An unique GUID that will be used to registration of a pipe.</param> /// <param name="connectionCallback"> /// A delegate that will be called when connection /// between the server an client will be established. /// </param> /// <param name="pipeName">A name of the pipe that will be used to access by clients.</param> /// <param name="pipeDirection">Dirrection of a data transmission.</param> /// <param name="allowedServerInstances">Count of server pipes those can be started with the same name.</param> /// <param name="transmissionMode">Specifies the transmission mode of the pipe.</param> /// <param name="pipeOptions">Configuration of the pipe.</param> /// <param name="securityLevel">A security lable that will be applied to the pipe.</param> /// <param name="initHandler"> /// A handler that will be called in case if transmission still not registred. /// Provides possibility to fulfill custom initialization specified for a certain transmission controller. /// </param> public static void ServerLoop <TransmissionControllerType>( string guid, Action <BaseServerTransmissionController> connectionCallback, string pipeName, PipeDirection pipeDirection, int allowedServerInstances, PipeTransmissionMode transmissionMode, PipeOptions pipeOptions, Security.SecurityLevel securityLevel, Action <BaseServerTransmissionController> initHandler = null) where TransmissionControllerType : BaseServerTransmissionController { // Creating a PipeSecurity relative to requesteed level. PipeSecurity pipeSecurity = Security.General.GetRulesForLevels(securityLevel); // Trying to open a pipe server. NamedPipeServerStream pipeServer = null; try { pipeServer = new NamedPipeServerStream( pipeName, pipeDirection, allowedServerInstances, transmissionMode, pipeOptions, 0, 0, pipeSecurity); } catch (Exception ex) { pipeServer.Dispose(); Console.WriteLine("{1}: SERVER LOOP NOT STARTED:\n{0}\n", ex.Message, pipeName); return; } //Console.WriteLine("{0}: Pipe created", pipeName); #region Meta data // Meta data about curent transmition. TransmissionControllerType transmisssionController = null; lock (openedServers) { // Registration or update controller of oppened transmission. if (openedServers[guid] is TransmissionControllerType bufer) { // Load previous contorller. transmisssionController = bufer; } else { // Create new controller. transmisssionController = (TransmissionControllerType)Activator.CreateInstance( typeof(TransmissionControllerType), new object[] { null, connectionCallback, pipeServer, pipeName }); // Call additive init. initHandler?.Invoke(transmisssionController); // Add to table. openedServers.Add(guid, transmisssionController); } } try { // Inform subscribers about new pass with this transmission to give possibility correct data. TransmissionToProcessing?.Invoke(transmisssionController); } catch (Exception ex) { Console.WriteLine("Server Loop. Transmission event fail. (SLTEF0): {0}", ex.Message); } #endregion #region Main loop while (!transmisssionController.Expired) { // Wait for a client to connect if ((transmisssionController.connectionMarker == null || transmisssionController.connectionMarker.IsCompleted) && !pipeServer.IsConnected && transmisssionController.NewConnectionSearchAllowed) { try { // Start async waiting of connection. transmisssionController.connectionMarker = pipeServer.BeginWaitForConnection( Handlers.Service.ConnectionEstablishedCallbackRetranslator, transmisssionController); // Update data. transmisssionController.NewConnectionSearchAllowed = false; Console.Write("{0}: Waiting for client connection...\n", pipeName); } catch //(Exception ex) { //Console.WriteLine("SERVER LOOP ERROR. SERVER RESTORED: {0}", ex.Message); // Close actual pipe. pipeServer.Close(); // Establish new server. pipeServer = new NamedPipeServerStream(pipeName, pipeDirection, allowedServerInstances, transmissionMode, pipeOptions, 0, 0, pipeSecurity); // Update meta data. transmisssionController.PipeServer = pipeServer; } //Console.WriteLine("TRANSMITION META HASH: {0}", meta.GetHashCode()); } // Turn order to other threads. Thread.Sleep(150); } #endregion // Finalize server. if (!transmisssionController.Stoped) { StopServer(transmisssionController); } // Discharge existing in hashtable. openedServers.Remove(guid); // Finish stream. pipeServer.Close(); pipeServer.Dispose(); Console.WriteLine("{0}: PIPE SERVER CLOSED", transmisssionController.PipeName); }