private void ManagerChannelProcess(TcpChannelContext context)
        {
            //登出管理连接
            if (_managerchannel_login > 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 _managerchannel_login);

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

            _manager_channel = context;
            context.OnManagerChannelMessage += Context_OnManagerChannelMessage;
        }
        private void SetSessionId(TcpChannelContext 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");

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

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

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

                    byte[] ack = target_context.AckPack;

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

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

                if (this._managerchannel_login > 0)
                {
                    LogShowQueueHelper.WriteLog("Set SessionId SessionCount:" + body.Length / (sizeof(Int64) * 2));
                }
            }
            catch (Exception e)
            {
                LogShowQueueHelper.WriteLog("Set SessionId Exception:" + e.Message, "err");
            }
        }
        private void ProcessPullMainChannel(TcpChannelContext context)
        {
            //查找所有MainChannel
            List <TcpChannelContext> 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 (_managerchannel_login > 0)
            {
                SendMessage(_manager_channel, MessageHelper.CommandCopyTo(MsgCommand.Msg_Set_Session, data));
                LogShowQueueHelper.WriteLog("Get Session SessionCount:" + contexts.Count);
            }
        }
        private void Context_TcpAwaitnotifyProc(TcpChannelContext context, TcpChannelContextServiceType type)
        {
            this.AddChannelListViewItem(context);

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

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

            case TcpChannelContextServiceType.WorkChannel:

                //通知发起工作连接
                if (this._managerchannel_login > 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 SessionClosed(TcpSocketSaeaSession session)
        {
            var context = ((TcpChannelContext)session.AppTokens[0]);

            context.OnClosed();
            context.OnChannelTypeNotify     -= 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._managerchannel_login > 0)
                {
                    Interlocked.Decrement(ref _managerchannel_login);
                }
                else
                {
                    _manager_channel = null;
                }
            }
            else if (context.ChannelType == TcpChannelContextServiceType.MainChannel)
            {
                byte[] data = BitConverter.GetBytes(context.RemoteId);

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

            if (context.ChannelType != TcpChannelContextServiceType.None)
            {
                this.RemoveChannelListViewItem(context);
            }
        }
示例#6
0
        public void OnMessage(TcpSocketSaeaSession session)
        {
            byte[] data = new byte[session.ReceiveBytesTransferred];
            Array.Copy(session.CompletedBuffer, 0, data, 0, data.Length);

            var type = (TcpChannelContextServiceType)session.AppTokens[1];

            if (type == TcpChannelContextServiceType.None)
            {
                //当通道类型未确认时,进入该区域处理消息

                _buffer.AddRange(data);
                if (_buffer.Count < 4)
                {
                    return;
                }

                byte[] lenBytes   = _buffer.GetRange(0, 4).ToArray();
                int    packageLen = BitConverter.ToInt32(lenBytes, 0);

                if (packageLen < 0 || packageLen > 1024 * 1024 * 2)
                {
                    session.Close(true);
                    return;
                }

                if (packageLen > _buffer.Count - 4)
                {
                    return;
                }

                //保留ack,与控制端连接时要用到
                this._ack_buffer = _buffer.GetRange(0, packageLen + 4).ToArray();

                byte[] Ack = CompressHelper.Decompress(_buffer.GetRange(4, packageLen).ToArray());

                short headMsg = BitConverter.ToInt16(Ack, 0);

                if (headMsg == AckPacket)
                {
                    //                                                    命令头            消息体             连接类型
                    this._channelType = (TcpChannelContextServiceType)Ack[sizeof(Int16) + sizeof(Int64) + sizeof(Byte) - 1];

                    if (this._channelType == TcpChannelContextServiceType.ManagerChannel)
                    {
                        long accessKey = BitConverter.ToInt64(Ack, 2);

                        if (!AccessKeyExamine.CheckOut(accessKey))//连接密码确认
                        {
                            LogShowQueueHelper.WriteLog("ManagerChannel AccessKey Wrong " + accessKey.ToString(), "err");

                            byte[] body = MessageHelper.CommandCopyTo(MsgCommand.Msg_AccessKeyWrong);

                            byte[] pack = new byte[body.Length + sizeof(Int32)];
                            BitConverter.GetBytes(body.Length).CopyTo(pack, 0);
                            body.CopyTo(pack, 4);

                            session.SendAsync(pack);
                            //session.Close(true);
                            return;
                        }
                    }

                    this._session.AppTokens[1] = this._channelType;

                    if (this._channelType == TcpChannelContextServiceType.ManagerWorkChannel ||
                        this._channelType == TcpChannelContextServiceType.ManagerChannel)
                    {
                        _buffer.RemoveRange(0, packageLen + 4);
                    }

                    this.OnChannelTypeNotify?.Invoke(this, this._channelType);

                    if (this._channelType == TcpChannelContextServiceType.ManagerChannel)
                    {
                        this.ManagerPackageProcess();//如果缓冲区还有数据
                    }
                }
                else
                {
                    session.Close(true);
                }
            }
            else if (type == TcpChannelContextServiceType.WorkChannel && this._isJoin)
            {
                if (this._desession == null)
                {
                    return;
                }

                this._desession.SendAsync(data);
            }
            else if (type == TcpChannelContextServiceType.ManagerWorkChannel && this._channelType != type)//当前连接类型为ManagerWorkChannel且当前通道类型为ManagerWorkChannel时表示通道此时未与工作类型关联,暂时将数据存放在缓存区,待关联时再将数据转发
            {
                if (this._session == null)
                {
                    return;
                }

                this._session.SendAsync(data);
            }
            else if (type == TcpChannelContextServiceType.ManagerChannel)
            {
                this._buffer.AddRange(data);
                this.ManagerPackageProcess();
            }
            else if (type == TcpChannelContextServiceType.MainChannel)
            {
                this.OnMainChannelMessage?.Invoke(this, data);//直接转发
            }
            else
            {
                _buffer.AddRange(data);
            }
        }
        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();
                    }));

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

                    _channelContexts.Add(context);
                    break;

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

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

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