private void ManagerChannelProcess(TcpSessionChannelContext context)
        {
            //登出管理连接
            if (_managerChannelLoginSign > 0)
            {
                //close所有mainContext
                //while (this._channelContexts.Count < 1)
                //{
                //    for (int i = 0; i < this._channelContexts.Count; i++)
                //    {

                //    }
                //    Thread.Sleep(10);
                //}


                byte[] body = MessageHelper.CommandCopyTo(MsgCommand.Msg_LogOut);
                SendMessage(_manager_channel, body);
                LogShowQueueHelper.WriteLog("ManagerChannel LogOut");
            }

            Interlocked.Increment(ref _managerChannelLoginSign);

            if (_manager_channel != null)
            {
                _manager_channel.OnManagerChannelMessage        -= Context_OnManagerChannelMessage;
                _manager_channel.OnChannelTypeCheckEventHandler -= Context_TcpAwaitnotifyProc;
            }

            _manager_channel = context;
            context.OnManagerChannelMessage += Context_OnManagerChannelMessage;
        }
        private void Context_OnManagerChannelMessage(TcpSessionChannelContext context, byte[] data)
        {
            MsgCommand msg = (MsgCommand)data[0];

            switch (msg)
            {
            case MsgCommand.Msg_Pull_Session:
                this.ProcessPullMainChannel(context);
                break;

            case MsgCommand.Msg_Set_Session_Id:
                this.SetSessionId(context, data);
                break;

            case MsgCommand.Msg_Close_Session:
                this.CloseSession(data);
                break;

            case MsgCommand.Msg_MessageData:
                this.ProcessSendMessage(data);
                break;

            default:
                break;
            }
        }
        private void MainChannelProcess(TcpSessionChannelContext context)
        {
            if (this._managerChannelLoginSign > 0)
            {
                //发送新上线会话的ID
                byte[] data = BitConverter.GetBytes(context.Id);
                SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_Set_Session, data));
            }

            context.OnMainChannelMessage += Context_OnMainChannelMessage;
        }
 private void AddChannelListViewItem(TcpSessionChannelContext context)
 {
     this.BeginInvoke(new Action(() =>
     {
         ChannelListViewItem item = new ChannelListViewItem(context);
         item.Text = DateTime.Now.ToString();
         item.SubItems.Add(context.ChannelType.ToString());
         item.SubItems.Add("0.00/0.00");
         this.channelListView.Items.Add(item);
     }));
 }
        private void SendMessage(TcpSessionChannelContext context, byte[] data)
        {
            byte[] body = new byte[sizeof(Int32) + data.Length];
            BitConverter.GetBytes(data.Length).CopyTo(body, 0);
            data.CopyTo(body, 4);

            if (context == null)
            {
                return;
            }

            context.SendMessage(body, 0, body.Length);
        }
        private void SetSessionId(TcpSessionChannelContext context, byte[] data)
        {
            byte[] body = new byte[data.Length - 1];
            Array.Copy(data, 1, body, 0, body.Length);

            try
            {
                byte[] sessionItems = new byte[sizeof(Int64) * 2];
                for (int i = 0; i < body.Length / (sizeof(Int64) * 2); i++)
                {
                    Array.Copy(body, i * sessionItems.Length, sessionItems, 0, sessionItems.Length);
                    long id = BitConverter.ToInt64(sessionItems, 0);

                    LogShowQueueHelper.WriteLog("DEBUG SetSessionId:" + id);

                    GCHandle gc = GCHandle.FromIntPtr(new IntPtr(id));

                    LogShowQueueHelper.WriteLog("DEBUG SetSessionId OK");

                    TcpSessionChannelContext target_context = gc.Target as TcpSessionChannelContext;
                    id = BitConverter.ToInt64(sessionItems, sizeof(Int64));

                    LogShowQueueHelper.WriteLog("DEBUG SetSessionId RmoteId:" + id);

                    //关联控制端SessionId
                    target_context.RemoteId = id;

                    byte[] ack = target_context.AckPacketData;

                    byte[] ackPack = new byte[ack.Length + sizeof(Int64)];
                    BitConverter.GetBytes(id).CopyTo(ackPack, 0);
                    ack.CopyTo(ackPack, sizeof(Int64));

                    //发送应用层连接确认报(连接密码等信息)
                    if (this._managerChannelLoginSign > 0)
                    {
                        SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_MessageData, ackPack));
                    }
                }

                if (this._managerChannelLoginSign > 0)
                {
                    LogShowQueueHelper.WriteLog("Set SessionId SessionCount:" + body.Length / (sizeof(Int64) * 2));
                }
            }
            catch (Exception e)
            {
                LogShowQueueHelper.WriteLog("Set SessionId Exception:" + e.Message, "err");
            }
        }
 private void RemoveChannelListViewItem(TcpSessionChannelContext context)
 {
     this.BeginInvoke(new Action(() =>
     {
         for (int i = 0; i < this.channelListView.Items.Count; i++)
         {
             ChannelListViewItem lv = this.channelListView.Items[i] as ChannelListViewItem;
             if (lv.TcpChannelContext.Id == context.Id)
             {
                 this.channelListView.Items.RemoveAt(i);
                 break;
             }
         }
     }));
 }
        private void CloseSession(byte[] data)
        {
            long id = BitConverter.ToInt64(data, 1);

            Console.WriteLine("CloseSession:" + id);
            GCHandle gc = GCHandle.FromIntPtr(new IntPtr(id));

            Console.WriteLine("CloseSession OK");
            TcpSessionChannelContext target_context = gc.Target as TcpSessionChannelContext;

            if (target_context == null)
            {
                return;
            }

            target_context.Session.Close(true);
        }
        private void Context_OnMainChannelMessage(TcpSessionChannelContext context, byte[] data)
        {
            if (this._managerChannelLoginSign == 0)
            {
                return;
            }

            byte[] bytes = new byte[sizeof(Int64) + data.Length];
            BitConverter.GetBytes(context.RemoteId).CopyTo(bytes, 0);
            data.CopyTo(bytes, sizeof(Int64));

            //MainChannel的数据封装代理协议发送出去
            if (this._managerChannelLoginSign > 0)
            {
                SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_MessageData, bytes));
            }
        }
        private void ProcessPullMainChannel(TcpSessionChannelContext context)
        {
            //查找所有MainChannel
            List <TcpSessionChannelContext> contexts = _channelContexts.Where(x => x.ChannelType == TcpChannelContextServiceType.MainChannel).ToList();

            byte[] data = new byte[contexts.Count * sizeof(Int64)];
            for (int i = 0; i < contexts.Count; i++)
            {
                BitConverter.GetBytes(contexts[i].Id).CopyTo(data, i * sizeof(Int64));
                Console.WriteLine("ProcessPullMainChannel:" + contexts[i].Id);
            }

            if (_managerChannelLoginSign > 0)
            {
                SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_Set_Session, data));
                LogShowQueueHelper.WriteLog("Get Session SessionCount:" + contexts.Count);
            }
        }
        private void ProcessSendMessage(byte[] data)
        {
            //byte[] body = new byte[data.Length - 1];
            //Array.Copy(data, 1, body, 0, body.Length);

            long id = BitConverter.ToInt64(data, 1);

            Console.WriteLine("ProcessSendMessage:" + id);
            GCHandle gc = GCHandle.FromIntPtr(new IntPtr(id));

            Console.WriteLine("ProcessSendMessage OK");
            TcpSessionChannelContext context = gc.Target as TcpSessionChannelContext;

            if (context == null)
            {
                return;
            }

            //将消息转发给MainChannel
            context.SendMessage(data, sizeof(Int64) + 1, data.Length - sizeof(Int64) - 1);
        }
        private void Context_TcpAwaitnotifyProc(TcpSessionChannelContext context, TcpChannelContextServiceType type)
        {
            this.AddChannelListViewItem(context);

            LogShowQueueHelper.WriteLog("连接被确认,工作类型:" + type.ToString());

            switch (type)
            {
            case TcpChannelContextServiceType.MainChannel:
                this.MainChannelProcess(context);
                break;

            case TcpChannelContextServiceType.WorkChannel:

                //通知发起工作连接
                if (this._managerChannelLoginSign > 0)
                {
                    SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_Connect_Work));
                }
                else
                {
                    context.Session.Close(true);
                }

                break;

            case TcpChannelContextServiceType.ManagerChannel:
                this.ManagerChannelProcess(context);
                break;

            case TcpChannelContextServiceType.ManagerWorkChannel:

                this.JoinWorkChannelContext(context);
                break;

            default:
                LogShowQueueHelper.WriteLog("未确认的连接:" + type.ToString());
                break;
            }
        }
        private void JoinWorkChannelContext(TcpSessionChannelContext context)
        {
            //查找没有关联过的WorkChannel
            TcpSessionChannelContext workContext = _channelContexts.Find(x => x.ChannelType == TcpChannelContextServiceType.WorkChannel && !x.IsJoin);

            if (workContext != null)
            {
                workContext.WorkChannelJoinContext(context.Session, context.GetBuffer);

                //关联完成,释放资源
                context.OnChannelTypeCheckEventHandler -= Context_TcpAwaitnotifyProc;
                context.OnClosed();

                this._channelContexts.Remove(context);
                this.RemoveChannelListViewItem(context);
            }
            else
            {
                //没找到就断开连接,回调会释放所有资源
                context.Session.Close(true);
            }
        }
        private void SessionClosed(TcpSocketSaeaSession session)
        {
            var context = ((TcpSessionChannelContext)session.AppTokens[SysContact.INDEX_CHANNELCONTEXT]);

            context.OnClosed();
            context.OnChannelTypeCheckEventHandler -= Context_TcpAwaitnotifyProc;
            context.OnManagerChannelMessage        -= Context_OnManagerChannelMessage;
            context.OnMainChannelMessage           -= Context_OnMainChannelMessage;

            _channelContexts.Remove(context);

            LogShowQueueHelper.WriteLog("有连接断开,工作类型:" + context.ChannelType, "err");

            if (context.ChannelType == TcpChannelContextServiceType.ManagerChannel)
            {
                if (this._managerChannelLoginSign > 0)
                {
                    Interlocked.Decrement(ref _managerChannelLoginSign);
                }
                else
                {
                    _manager_channel = null;
                }
            }
            else if (context.ChannelType == TcpChannelContextServiceType.MainChannel)
            {
                byte[] data = BitConverter.GetBytes(context.RemoteId);

                if (this._managerChannelLoginSign > 0)
                {
                    SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_Close_Session, data));
                }
            }

            if (context.ChannelType != TcpChannelContextServiceType.None)
            {
                this.RemoveChannelListViewItem(context);
            }
        }
        private void SessionProviderService_Load(object sender, EventArgs e)
        {
            this.Text = "SiMay中间会话服务-IOASJHD BEAT " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();

            IntPtr sysMenuHandle = GetSystemMenu(this.Handle, false);

            InsertMenu(sysMenuHandle, 7, MF_SEPARATOR, 0, null);
            InsertMenu(sysMenuHandle, 8, MF_BYPOSITION, IDM_OPTIONS, "系统设置");
            InsertMenu(sysMenuHandle, 9, MF_BYPOSITION, IDM_RUNLOG, "运行日志");

            _log_imgList = new ImageList();
            _log_imgList.Images.Add("ok", Resources.ok);
            _log_imgList.Images.Add("err", Resources.erro);

            logList.SmallImageList = _log_imgList;

            string address = ApplicationConfiguration.IPAddress;
            string port    = ApplicationConfiguration.Port;

            this.lableIPAddress.Text = address;
            this.labelPort.Text      = port;
            this.lableStatrTime.Text = DateTime.Now.ToString();
            var ipe = new IPEndPoint(IPAddress.Parse(address), int.Parse(port));


            var serverConfig = new TcpSocketSaeaServerConfiguration();

            serverConfig.ReuseAddress             = false;
            serverConfig.KeepAlive                = true;
            serverConfig.KeepAliveInterval        = 5000;
            serverConfig.KeepAliveSpanTime        = 1000;
            serverConfig.PendingConnectionBacklog = int.Parse(ApplicationConfiguration.Backlog);

            _server = TcpSocketsFactory.CreateServerAgent(TcpSocketSaeaSessionType.Full, serverConfig, (notify, session) =>
            {
                switch (notify)
                {
                case TcpSocketCompletionNotify.OnConnected:
                    _connectionCount++;

                    this.Invoke(new Action(() =>
                    {
                        this.lableConnectionCount.Text = _connectionCount.ToString();
                    }));

                    //创建通道上下文,等待确认通道类型
                    TcpSessionChannelContext context        = new TcpSessionChannelContext(session);
                    context.OnChannelTypeCheckEventHandler += Context_TcpAwaitnotifyProc;

                    _channelContexts.Add(context);
                    break;

                case TcpSocketCompletionNotify.OnSend:
                    this._uploadTransferBytes += session.SendTransferredBytes;
                    break;

                case TcpSocketCompletionNotify.OnDataReceiveing:
                    this._receiveTransferBytes += session.ReceiveBytesTransferred;

                    ((TcpSessionChannelContext)session.AppTokens[0]).OnMessage(session);
                    break;

                case TcpSocketCompletionNotify.OnClosed:
                    _connectionCount--;

                    this.Invoke(new Action(() =>
                    {
                        this.lableConnectionCount.Text = _connectionCount.ToString();
                    }));

                    this.SessionClosed(session);
                    break;

                default:
                    break;
                }
            });
            try
            {
                _server.Listen(ipe);
                LogShowQueueHelper.WriteLog("SiMay中间会话服务端口" + port + "启动成功!");
            }
            catch
            {
                LogShowQueueHelper.WriteLog("SiMay中间会话服务端口" + port + "启动失败!", "err");
            }

            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 100;
            timer.Elapsed += Timer_Elapsed;
            timer.Start();

            System.Timers.Timer flow_timer = new System.Timers.Timer();
            flow_timer.Interval = 1000;
            flow_timer.Elapsed += Flow_timer_Elapsed;
            flow_timer.Start();
        }