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