private void BeginReadCallback(IAsyncResult result)
        {
            string    pipeId = (string)result.AsyncState;
            EventPipe pipe   = s_pipes[pipeId];

            int    readBytes = pipe.InPipe.EndRead(result);
            string msg       = ToString(pipe.InMsgBuf, readBytes);

            if (readBytes > 0 && (s_pipeStopMsg != null && msg != s_pipeStopMsg))
            {
                try {
                    PipeMessage pmsg = JsonConvert.DeserializeObject <PipeMessage>(msg);
                    log.Debug($"Client message received, type: {pmsg.type}, msg: {pmsg.message} ");

                    // Embed echo function for client testing
                    Echo(pmsg, pipe.Id);

                    if (OnMessage != null)
                    {
                        OnMessage(pmsg, pipeId);
                    }
                } catch (Exception ex)
                {
                    log.Error($"Failed to process received message: {msg}, ex: {ex}");
                }

                pipe.InPipe.BeginRead(pipe.InMsgBuf, 0, BUFFER_SIZE, BeginReadCallback, pipe.Id);
            }
            else
            {
                log.Debug("Receive empty or stop message, client disconnected or broken.");
                RestartConnectionWaiting(pipe.Id);
            }
        }
 public void SendMsg(PipeMessage msg)
 {
     foreach (var pipeKV in s_pipes)
     {
         EventPipe pipe = pipeKV.Value;
         try {
             if (pipe.OutPipe.IsConnected && pipe.OutPipe.CanWrite)
             {
                 log.Debug($"Sending to {pipe.Id}, message: {msg}");
                 byte[] msgBytes = Encoding.UTF8.GetBytes(msg.ToString());
                 pipe.OutPipe.Write(msgBytes, 0, msgBytes.Length);
                 pipe.OutPipe.Flush();
             }
         }
         catch (Exception ex)
         {
             log.Debug($"Write message failed. Pipe {pipe.Id} should have broken. ex: {ex}");
             if (OnDisconnected != null)
             {
                 OnDisconnected(pipe.Id);
             }
             RestartConnectionWaiting(pipe.Id);
         }
     }
 }
 public void Stop()
 {
     foreach (var pipeKV in s_pipes)
     {
         EventPipe pipe = pipeKV.Value;
         pipe.Stop();
     }
 }
 public void Start()
 {
     try
     {
         // Init named pipe
         for (int i = 0; i < s_maxServerInstances; i++)
         {
             EventPipe pipe = new EventPipe(s_InPipeName, s_OutPipeName, s_maxServerInstances, s_pipeSecurity);
             pipe.Start(InConnectionCallBack, OutConnectionCallBack);
             s_pipes.Add(pipe.Id, pipe);
         }
     }
     catch (Exception ex)
     {
         log.Error(ex);
         throw ex;
     }
 }
        private void InConnectionCallBack(IAsyncResult result)
        {
            string    pipeId = (string)result.AsyncState;
            EventPipe pipe   = s_pipes[pipeId];

            try
            {
                pipe.InPipe.EndWaitForConnection(result);

                // Start async read for connection status checking
                pipe.InPipe.BeginRead(pipe.InMsgBuf, 0, BUFFER_SIZE, BeginReadCallback, pipe.Id);
            }
            catch (Exception ex)
            {
                log.Error("Exception in BeginRead for InPipe, restart waiting. ex: " + ex);
                RestartConnectionWaiting(pipe.Id);
            }
        }
        private void OutConnectionCallBack(IAsyncResult result)
        {
            string    pipeId = (string)result.AsyncState;
            EventPipe pipe   = s_pipes[pipeId];

            try
            {
                pipe.OutPipe.EndWaitForConnection(result);

                if (s_pipeStartMsg != null)
                {
                    int    readBytes = pipe.OutPipe.Read(pipe.OutMsgBuf, 0, BUFFER_SIZE);
                    string msg       = ToString(pipe.OutMsgBuf, readBytes);

                    // Check start message
                    if (readBytes <= 0 || msg != s_pipeStartMsg)
                    {
                        log.Error($"HandleMessage: empty content or invalid start message: " + msg);
                        RestartConnectionWaiting(pipe.Id);
                        return;
                    }
                }

                // Send ack message
                log.Debug($"Pipe {pipe.Id} Connected.");
                PipeMessage ackMsg      = new PipeMessage("Ack", $"Command pipe Connected! Id: {pipe.Id}, PipeName: {s_OutPipeName}");
                byte[]      ackMsgBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(ackMsg));
                pipe.OutPipe.Write(ackMsgBytes, 0, ackMsgBytes.Length);

                // Update status
                pipe.Status = ConnStatus.Connected;

                // Run user action
                if (OnConnected != null)
                {
                    OnConnected(pipeId);
                }
            }
            catch (Exception ex)
            {
                log.Error("Exception while waiting for connection to OutPipe, restart waiting , ex: " + ex);
                RestartConnectionWaiting(pipe.Id);
            }
        }
        private void RestartConnectionWaiting(string pipeId)
        {
            log.Info("RestartWaiting!");
            EventPipe pipe = null;

            try
            {
                pipe = s_pipes[pipeId];
                pipe.Stop();
            }
            catch (Exception ex)
            {
                log.Warn("Clean up connection failed: " + ex);
            }
            finally
            {
                // Restart stream to wait for new connection
                if (pipe != null)
                {
                    pipe.Start(InConnectionCallBack, OutConnectionCallBack);
                }
            }
        }