public CommandClient(string ipAddress, int port, string host, string protocol, IWebSocketClientSessionFactory sessionFactory, ICommandParser commandParser)
        {
            logger = LoggerManager.GetLogger(String.Format("CommandClient_{0}_{1}", ipAddress, port));
            SessionCommandParser = commandParser;
            IsConnecting         = false;

            IP                    = ipAddress;
            Port                  = port;
            RequestTimeout        = TimeSpan.FromMinutes(2);
            MaxRetryCount         = 3;
            IsAync                = true;
            Session               = new CommandSession();
            Session.CommandParser = commandParser;
            IsConnected           = false;
            CommandAliveTime      = TimeSpan.FromMinutes(2);
            CommandList           = new List <ICommand>();

            CommandList.Add(new SetCommandParserResponse());

            CommandParser = new List <ICommandParser>()
            {
                new WSCommandType(),
                new WSBinaryCommandType()
            };

            client = new WebSocketClient(host, "", protocol, sessionFactory);

            client.Connected       += new EventHandler <WebSocketConnectedEventArgs>(ClientConnected);
            client.Closed          += new EventHandler(ClientClosed);
            client.MessageReceived += new EventHandler <MessageReceivedEventArgs>(MessageReceived);
        }
        protected virtual void HandshakeCompleted(object sender, EventArgs e)
        {
            WebSocketSessionBase ws = sender as WebSocketSessionBase;

            if (ws != null)
            {
                if (ClientConnected != null)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
                    {
                        CommandSession cs = null;
                        lock (lockerObj)
                        {
                            if (SessionList.ContainsKey(ws.SessionID))
                            {
                                cs = SessionList[ws.SessionID];
                            }
                        }
                        if (cs != null)
                        {
                            ClientConnected(this, cs);
                        }
                    }), null);
                }
            }
        }
 public virtual void SendCommand(CommandSession session, WSCommandTypeBase command, CommandResponse callback)
 {
     if (session == null)
     {
         return;
     }
     session.SendCommand(command, callback);
 }
        public virtual CommandItem <WSCommandTypeBase> SendCommandSync(CommandSession session, WSCommandTypeBase command)
        {
            if (session == null)
            {
                return(null);
            }

            return(session.SendCommandSync(command, RequestTimeout));
        }
 void ws_SessionIDChanged(object sender, SessionIDChangedEventArgs e)
 {
     lock (lockerObj)
     {
         CommandSession oldSession = SessionList[e.Old];
         SessionList.Remove(e.Old);
         SessionList.Add(e.New, oldSession);
     }
 }
 public virtual void DettachSession(CommandSession commandSession)
 {
     if (commandSession == null)
     {
         return;
     }
     lock (lockerObj)
     {
         SessionList.Remove(commandSession.Session.SessionID);
         application.DettachSession(commandSession.Session);
     }
 }
        protected void SetReplyCommand(CommandSession client, ICommand replayCmd, MessageReceivedEventArgs e, Guid requestGuid, ICommandParser cmdParser)
        {
            if (replayCmd != null)
            {
                WSCommandTypeBase replyCommandType = cmdParser.Create();
                replayCmd.ToCommand(replyCommandType);


                replyCommandType.RequestID = requestGuid;
                cmdParser.SetReplyCommand(e, replyCommandType);
                if (IsAync)
                {
                    //异步需要自己向Session发送消息
                    client.Session.SendMessage(cmdParser.ToBinary(replyCommandType), cmdParser.TransferEncoder);
                }
            }
        }
        //public virtual void AttachSession(WebSocketSessionBase session)
        //{
        //    application.AttachSession(session);
        //    SessionStarted(session, EventArgs.Empty);
        //}

        //public virtual void DettachSession(WebSocketSessionBase session)
        //{
        //    lock (lockerObj)
        //    {
        //        SessionList.Remove(session.SessionID);
        //        application.DettachSession(session);
        //    }

        //}

        public virtual void AttachSession(CommandSession commandSession)
        {
            if (commandSession == null)
            {
                logger.Warn("AttachSession 传入Session为空");
                return;
            }
            application.AttachSession(commandSession.Session);
            WebSocketSessionBase ws = commandSession.Session as WebSocketSessionBase;

            if (ws != null)
            {
                ws.SessionIDChanged += new EventHandler <SessionIDChangedEventArgs>(ws_SessionIDChanged);

                lock (lockerObj)
                {
                    SessionList.Add(ws.SessionID, commandSession);
                }
            }
        }
        protected virtual void SessionStarted(object sender, EventArgs e)
        {
            WebSocketSessionBase ws = sender as WebSocketSessionBase;

            ws.SessionIDChanged += new EventHandler <SessionIDChangedEventArgs>(ws_SessionIDChanged);

            CommandSession session = new CommandSession()
            {
                Session = ws
            };

            if (session.CommandParser == null)
            {
                session.CommandParser = DefaultCommandParser;
            }
            if (ws != null)
            {
                lock (lockerObj)
                {
                    SessionList.Add(ws.SessionID, session);
                }
            }
        }
        protected virtual void SessionClosed(object sender, EventArgs e)
        {
            WebSocketSessionBase ws     = sender as WebSocketSessionBase;
            CommandSession       client = null;

            lock (lockerObj)
            {
                if (SessionList.ContainsKey(ws.SessionID))
                {
                    client = SessionList[ws.SessionID];
                }
            }

            if (client == null)
            {
                return;
            }

            if (client != null)
            {
                if (ClientClosed != null)
                {
                    ClientClosed(this, client);
                }
            }
            if (ws != null)
            {
                lock (lockerObj)
                {
                    try
                    {
                        SessionList.Remove(ws.SessionID);
                    }
                    catch { }
                }
            }
        }
 public void SendCommand(CommandSession session, WSCommandTypeBase command)
 {
     SendCommand(session, command, null);
 }
        //public void Broadcast(WSCommandType command)
        //{
        //    if (command == null)
        //        return;

        //    command.RequestID = Guid.NewGuid();
        //    command.OccurTime = DateTime.Now;
        //    string commandText = SerializationUtility.ToXmlString(command);
        //    application.Broadcast(commandText);
        //}

        //public void Broadcast(WSCommandType command, Func<WebSocketSession, bool> checkFunc)
        //{
        //    if (command == null)
        //        return;

        //    command.RequestID = Guid.NewGuid();
        //    command.OccurTime = DateTime.Now;
        //    string commandText = SerializationUtility.ToXmlString(command);
        //    application.Broadcast(commandText, checkFunc);
        //}

        //public void Broadcast(WSBinaryCommandType command)
        //{
        //    if (command == null)
        //    {
        //        return;
        //    }
        //    command.RequestID = Guid.NewGuid();
        //    command.OccurTime = DateTime.Now;
        //    byte[] commandData = BinaryCommandTypeSerializer.ToBinary(command);
        //    application.Broadcast(commandData);
        //}

        //public void Broadcast(WSBinaryCommandType command, Func<WebSocketSession,bool> checkFunc)
        //{
        //    if (command == null)
        //    {
        //        return;
        //    }
        //    command.RequestID = Guid.NewGuid();
        //    command.OccurTime = DateTime.Now;
        //    byte[] commandData = BinaryCommandTypeSerializer.ToBinary(command);
        //    application.Broadcast(commandData, checkFunc);
        //}

        public void SendCommand(CommandSession session, ICommand command)
        {
            session.SendCommand(command);
        }
        public bool ProcessMessage(MessageReceivedEventArgs e, List <ICommand> commandList)
        {
            ICommandParser    cmdParser;
            WSCommandTypeBase cmd = GetRequestCommand(e, out cmdParser);

            if (cmd == null)
            {
                return(false);
            }

            bool isProcessed = false;

            if (cmd != null)
            {
                // 关于是否触发CommandReceived事件:
                //      当使用带有回调方法的SendCommand发送命令时,接收到应答命令时不会触发CommandReceived事件
                //      当使用SendCommandSync方法发送同步返回的命令时,接收到应答命令时不会触发CommandReceived事件
                //      当接收到的命令能够被内置的CommandList处理时,会触发CommandReceived事件,并且自动设置ReplyCommand为执行完后返回的命令,
                // 同时将事件参数中的IsUnknown属性设置为false。
                //      当接收到的命令不属于上述任一情况时,将触发CommandReceived事件,并将IsUnknown属性设置为true



                CommandSession client = null;
                lock (lockerObj)
                {
                    if (SessionList.ContainsKey(e.Session.SessionID))
                    {
                        client = SessionList[e.Session.SessionID];
                    }
                }

                if (client == null)
                {
                    return(false);
                }
                CommandItem <WSCommandTypeBase> ci = null;
                lock (client.SyncLocker)
                {
                    ci = client.Commands.OfType <CommandItem <WSCommandTypeBase> >().FirstOrDefault(x => x.CommandRequest != null && x.CommandRequest.IsPairCommand(cmd));
                }
                CommandReceivedEventArgs <WSCommandTypeBase> args = new CommandReceivedEventArgs <WSCommandTypeBase>(cmd);
                args.IsUnknwon = true;

                // 检查命令是否能被内置命令列表处理
                ICommand exeCommand          = commandList.FirstOrDefault(x => x.CanExecute(cmd));
                ICommand replyCommand        = null;
                bool     isFireReceivedEvent = true;
                if (exeCommand != null)
                {
                    try
                    {
                        replyCommand = exeCommand.Execute(cmd, new ExecuteCommandContext()
                        {
                            CommandSession = client
                        });
                        isProcessed = true;
                    }
                    catch (Exception ex)
                    {
                        logger.Error("执行命令失败:{0} \r\n{1}", cmd.CommandName, ex.ToString());
                    }



                    args.IsUnknwon = false;
                }


                args.Session = client;
                if (ci != null)
                {
                    ci.CommandResponse  = cmd;
                    args.RequestCommand = ci.CommandRequest;
                    lock (client.SyncLocker)
                    {
                        if (cmd.IsOver)
                        {
                            client.Commands.Remove(ci);
                        }
                    }
                    if (ci.ResponseCallback != null)
                    {
                        ci.ResponseCallback(ci);
                        isFireReceivedEvent = false;
                    }

                    if (ci.IsSync)
                    {
                        ci.Wait.Set();
                        isFireReceivedEvent = false;
                    }
                }

                if (isFireReceivedEvent)
                {
                    onCommandReceived(args);
                }

                SetReplyCommand(client, replyCommand, e, cmd.RequestID, cmdParser);
            }

            return(isProcessed);
        }