public virtual T SendCommandSync <T>(ICommand command, TimeSpan timeout) where T : CommandBase, new()
        {
            CommandItem <WSCommandTypeBase> response = SendCommandSync(command, timeout);

            if (response != null && response.CommandResponse != null)
            {
                CommandBase responseCommand = new T();
                responseCommand.LoadCommand(response.CommandResponse);
                return(responseCommand as T);
            }

            return(null);
        }
 public virtual void SendCommand <T>(ICommand command, CommandCallback <T> callback)
     where T : CommandBase, new()
 {
     SendCommand(command, new CommandResponse((ci) =>
     {
         if (callback != null && ci != null)
         {
             CommandItem <WSCommandTypeBase> actualCi = ci as CommandItem <WSCommandTypeBase>;
             if (actualCi != null && actualCi.CommandResponse != null)
             {
                 T responseCmd = new T();
                 responseCmd.LoadCommand(actualCi.CommandResponse);
                 callback(responseCmd);
             }
         }
     }));
 }
        //在子类中实现此方法,用于插入触发Connected事件之前的特殊处理
        protected virtual bool OnBeforeConnected()
        {
            bool isSuccess = false;

            Debug.WriteLine("Client Socket Status:" + Session.Session.SessionID + " " + Session.Session.ClientSocket.Connected.ToString());
            CommandItem <WSCommandTypeBase> response = Session.SendCommandSync(new SetCommandParserRequest(SessionCommandParser.ParserID), RequestTimeout);

            if (response != null && response.CommandResponse != null)
            {
                SetCommandParserResponse cmdParserResponse = new SetCommandParserResponse(response.CommandResponse);
                if (cmdParserResponse.IsSuccess)
                {
                    isSuccess = true;
                }
            }

            return(isSuccess);
            //  return true;
        }
        public virtual CommandItem <WSCommandTypeBase> SendCommandSync(ICommand command, TimeSpan timeout)
        {
            if (command == null)
            {
                return(null);
            }
            WSCommandTypeBase wsCommand = CommandParser.Create();

            command.ToCommand(wsCommand);

            wsCommand.RequestID     = Guid.NewGuid();
            Session.LastRequestTime = DateTime.Now;

            CommandItem <WSCommandTypeBase> ci = new CommandItem <WSCommandTypeBase>()
            {
                CommandRequest   = wsCommand,
                CommandResponse  = null,
                RetryCount       = 0,
                ResponseCallback = null,
                RequestTime      = DateTime.Now,
                IsSync           = true,
                Wait             = new System.Threading.AutoResetEvent(false)
            };

            lock (SyncLocker)
            {
                Commands.Add(ci);
            }

            logger.Trace("发送命令:{0}", wsCommand.CommandName);
            bool isSended = Session.SendMessage(CommandParser.ToBinary(wsCommand), CommandParser.TransferEncoder);

            if (!isSended)
            {
                return(ci);
            }

            ci.Wait.WaitOne(timeout);

            return(ci);
        }
        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

                CommandItem <WSCommandTypeBase> ci = null;
                lock (Session.SyncLocker)
                {
                    ci = Session.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 = Session
                        });
                        isProcessed = true;
                    }
                    catch (Exception ex)
                    {
                        logger.Error("执行命令失败:{0} \r\n{1}", cmd.CommandName, ex.ToString());
                    }


                    args.IsUnknwon = false;
                }


                args.Session = Session;
                if (ci != null)
                {
                    ci.CommandResponse  = cmd;
                    args.RequestCommand = ci.CommandRequest;
                    lock (Session.SyncLocker)
                    {
                        if (cmd.IsOver)
                        {
                            Session.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(Session, replyCommand, e, cmd.RequestID, cmdParser);
            }

            return(isProcessed);
        }