Exemplo n.º 1
0
 private void DoStart(NetWorkMsg msg)
 {
     try
     {
         DxDebug.LogConsole("DNServer.DoStart():工作线程开始执行DoStart()...");
         if (_socketListener != null)
         {
             DxDebug.Log(" DNServer.DoStart():_socketListener.Dispose();");
             _socketListener.Dispose();
         }
         DxDebug.Log("DNServer.DoStart():_socketListener = new SocketListener(CONNECTIONS_BUFFER_SIZE);");
         _socketListener = new SocketListener(this, CONNECTIONS_BUFFER_SIZE);
         DxDebug.Log("DNServer.DoStart():_socketListener.EventAccept += OnAccept;");
         _socketListener.EventAccept  += OnAccept;
         _socketListener.EventReceive += OnReceive;
         _socketListener.EventSend    += OnSend;
         _socketListener.EventError   += OnTokenError;
         DxDebug.Log("DNServer.DoStart(): _socketListener.Start(" + _port + ");");
         _socketListener.Start(msg.text1, _port);
         DxDebug.LogConsole("DNServer.DoStart()执行完毕!");
     }
     catch (Exception e)
     {
         DxDebug.LogWarning("DNServer.DoStart():异常 " + e.Message);
     }
 }
Exemplo n.º 2
0
        private void DoClose()
        {
            try
            {
                IsInited = false;
                DxDebug.LogConsole("DNClient.DoClose():开始释放资源 ");
                _disposed = true;

                // 清理托管资源
                _msgQueue.Clear();
                _msgPool.Clear();

                _msgQueue = null;
                _msgPool  = null;

                // 清理非托管资源
                _msgSemaphore.Close();
                _msgSemaphore = null;
                Interlocked.Exchange(ref _curSemCount, 0);

                if (_socketClient != null)
                {
                    _socketClient.Dispose();
                    _socketClient = null;
                }

                IsConnecting = false;
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.DoClose():异常: " + e.Message);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 发生错误后就关闭连接
        /// </summary>
        /// <param name="e"></param>
        private void ProcessError(SocketAsyncEventArgs e)
        {
            DxDebug.LogWarning("SocketClient.ProcessError():进入了ProcessError.  ErroType:" + e.SocketError); //显示下接收的信息
            Socket s = e.UserToken as Socket;                                                              //使用传递的Token

            if (s.Connected)
            {
                try
                {
                    DxDebug.LogConsole("SocketClient.ProcessError():调用Shutdown()关闭连接");
                    s.Shutdown(SocketShutdown.Both);
                }
                catch (Exception ex)
                {
                    DxDebug.LogWarning("SocketClient.ProcessError() :Shutdown()异常 " + ex.Message);
                }
                finally
                {
                    if (s.Connected)
                    {
                        s.Close();
                        DxDebug.LogWarning("SocketClient.ProcessError() :调用Close()关闭了连接");//这里是否必须要关闭待定
                    }
                }
            }
            //产生错误事件,这是一个很重要的事件,处理服务器连接断开等
            if (EventError != null)
            {
                EventError();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 开始接受客户端的Accept
        /// </summary>
        private void StartAccept(SocketAsyncEventArgs eArg)
        {
            //lock (_lockAccept)//这个加锁没有解决问题
            //{
            try
            {
                if (eArg == null)
                {
                    eArg            = new SocketAsyncEventArgs();
                    eArg.Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted);
                }

                eArg.AcceptSocket = null;   // 必须要先清掉Socket

                DxDebug.LogConsole("SocketListener.StartAccept():服务器开始接收认证!");
                //开始异步接收认证
                if (!_listenSocket.AcceptAsync(eArg))
                {
                    this.ProcessAccept(eArg);
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("SocketListener.StartAccept():异常:" + e.Message);
                // throw;
            }
            //}
        }
Exemplo n.º 5
0
        /// <summary>
        /// 由Socket开始一个异步发送
        /// </summary>
        /// <param name="token"></param>
        /// <param name="data"></param>
        internal void Send(Token token, byte[] data)
        {
            int errorCount = 0;

            try
            {
                if (token.disposed == false)       //如果这个token已经被释放,那就不要再发送了
                {
                    token.IncrementSendingCount(); //计数递增:这里需要及早标记,否则多线程调用SocketAsyncEventArgs会异常。

                    SocketAsyncEventArgs sendEventArgs = token.SendArgs;
                    sendEventArgs.SetBuffer(data, 0, data.Length);

                    //这里这个有可能会出现异常:"现在已经正在使用此 SocketAsyncEventArgs 实例进行异步套接字操作。
                    //所以这句可能要加锁
                    if (!token.socket.SendAsync(sendEventArgs))  //开始发送  ,这里作异常处理()
                    {
                        OnCompletedProcessSend(this, sendEventArgs);
                    }
                }
            }
            catch (Exception e)
            {
                errorCount++;
                DxDebug.LogWarning("SocketListener.Send():异常:" + e.Message);
                token.DecrementSendingCount();//直接异常了就去掉这个计数递减
                if (errorCount <= 2)
                {
                    DxDebug.LogConsole("SocketListener.Send()尝试自动重试!errorCount=" + errorCount);
                    Send(token, data);
                }
            }
        }
Exemplo n.º 6
0
        private void OnSend()
        {
            if (_isDebugLog)
            {
                DxDebug.LogConsole("-----------EventHandler.OnSend():进入OnSend回调!");
            }

            Interlocked.Decrement(ref _snedingCount);
            if (_packet2.SendMsgCount > 0) //如果待发送队列里有消息,不需要再判断_snedingCount < MAX_SENDING_DATA,直接开始下一次发送
            {
                NetWorkMsg msg = _msgPool.Dequeue();
                if (msg == null)
                {
                    msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Send);
                }
                else
                {
                    msg.Reset(NetWorkMsg.Tpye.C_Send);
                }
                AddMessage(msg);
            }
            else
            {
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// 根据期望大小获得一个buffer.
        /// autoSetValidLength为true则默认设置validLength为期望大小,否则设置为0.
        /// </summary>
        /// <param name="size">期望大小</param>
        /// <param name="autoSetValidLength">是否validLength会自动标记为size</param>
        /// <returns></returns>
        public ByteBuffer GetBuffer(long size, bool autoSetValidLength = false)
        {
            ByteBuffer bbf = null;

            if (size > maxBlockSize)
            {
                ByteBufferPool.countNew++;
                DxDebug.LogConsole("ByteBufferPools.GetBuffer():申请了一块过大的内存,size=" + size);
                //这个内存块太了,所以就不作缓存了
                bbf = new ByteBuffer(size);
            }
            else
            {
                ByteBufferPool bbPool = ChoosePool(size);
                bbf = bbPool.GetBuffer((int)size);
            }
            if (autoSetValidLength)
            {
                bbf.validLength = (int)size;
            }
            else
            {
                bbf.validLength = 0;
            }
            return(bbf);
        }
Exemplo n.º 8
0
        private void Dispose(bool disposing)
        {
            DxDebug.LogConsole(String.Format("TokenManager.Dispose():进入了Dispose!"));
            if (disposed)
            {
                return;
            }
            if (disposing)
            {
                // 清理托管资源
                EventAddToken    = null;
                EventDeleteToken = null;

                //断开所有
                DeleteAllToken();

                _dictToken.Clear();
                _dictToken = null;
                _arrToken  = null;
            }
            // 清理非托管资源

            //让类型知道自己已经被释放
            disposed = true;
        }
Exemplo n.º 9
0
        /// <summary>
        /// 删除一个token,会自动关闭连接。会产生事件
        /// </summary>
        /// <param name="id">根据ID删除已个Token</param>
        public void DeleteToken(int id)
        {
            CloseToken(id, TokenErrorType.UserDelete);//先关闭
            lock (this._lockDict)
            {
                if (_dictToken.ContainsKey(id))
                {
                    _dictToken.Remove(id);

                    _isDictEqualArr = false;//标记当前字典和数组已经不一致了
                }
                else
                {
                    return;
                }
            }
            if (EventDeleteToken != null)//事件
            {
                try
                {
                    EventDeleteToken(id, TokenErrorType.UserDelete);//这个是外部的调用删除
                }
                catch (Exception e)
                {
                    DxDebug.LogWarning("TokenManager.DeleteToken():执行事件EventDeleteToken异常!" + e.Message);
                }
            }

            DxDebug.LogConsole(String.Format("TokenManager.DeleteToken():关闭了一个客户端. 还有{0}个客户端,原因{1}", _dictToken.Count, TokenErrorType.UserDelete.ToString()));
        }
Exemplo n.º 10
0
        /// <summary>
        /// 添加一个token
        /// </summary>
        /// <param name="token"></param>
        internal Token AddToken(Token token)
        {
            lock (this._lockDict)
            {
                token.ID = _curID;
                _dictToken.Add(token.ID, token);
                //递增ID计数,额,不过上面已经加锁了
                Interlocked.Increment(ref _curID);

                _isDictEqualArr = false; //标记当前字典和列表已经不一致了
            }
            if (EventAddToken != null)   //事件
            {
                try
                {
                    EventAddToken(token.ID);
                }
                catch (Exception e)
                {
                    DxDebug.LogWarning("TokenManager.AddToken():执行事件EventAddToken异常!" + e.Message);
                }
            }
            DxDebug.LogConsole(String.Format("TokenManager.AddToken():添加了一个客户端. 当前服务器上有{0}个客户端; ip:{1}", _dictToken.Count, token.IP));
            return(token);
        }
Exemplo n.º 11
0
        /// <summary>
        /// 启动服务器,会开启工作线程然后释放一个DoStart信号量。
        /// </summary>
        /// <param name="port">端口号</param>
        /// <param name="threadCount">服务器使用的处理线程数量</param>
        /// <param name="hostName">服务器的主机IP,一般使用Any表示所有的可能IP</param>
        public void Start(int port, int threadCount = 1, string hostName = "Any")
        {
            try
            {
                DxDebug.LogConsole("DNServer.Start():服务器工作线程数 " + threadCount);
                if (disposed)
                {
                    TokenManager.GetInst().Clear();
                    _msgQueue     = new DQueue <NetWorkMsg>(MSG_QUEUE_CAPACITY);
                    _msgSemaphore = new Semaphore(0, MSG_QUEUE_CAPACITY);

                    _workThread = new Thread[threadCount];
                    for (int i = 0; i < threadCount; i++)
                    {
                        _workThread[i] = new Thread(DoWork);
                        _workThread[i].IsBackground = true;
                        //工作线程的优先级(影响不大)
                        _workThread[i].Priority = ThreadPriority.Highest;
                        _workThread[i].Name     = "SeverThread " + i;
                        _workThread[i].Start(); //启动线程
                    }

                    disposed = false;
                }

                _port = port;
                NetWorkMsg msg = new NetWorkMsg(NetWorkMsg.Tpye.S_Start, null);
                msg.text1 = hostName;
                AddMessage(msg);
            }
            catch (Exception e)
            {
                DxDebug.LogError("DNServer.Start():异常 " + e.Message);
            }
        }
Exemplo n.º 12
0
        private void DoWork()
        {
            DxDebug.LogConsole("DNServer.DoWork():服务器线程启动!");
            while (true)
            {
                _msgSemaphore.WaitOne();
                Interlocked.Decrement(ref _curSemCount);
                while (true)
                {
                    _cpuTime.WorkStart(); //时间分析计时
#if Multitask
                    NetWorkMsg msg1 = _msgQueue.Dequeue();
                    NetWorkMsg msg2 = _msgQueue.Dequeue();
                    if (msg1 == null && msg2 == null)
                    {
                        break;
                    }
                    else if (msg1 != null && msg2 != null)//取到了两条消息
                    {
                        //再消耗一条信号量
                        //_msgSemaphore.WaitOne();
                        Interlocked.Decrement(ref _curSemCount);
                        Parallel.Invoke(delegate() { ProcessMsg(msg1); }, delegate() { ProcessMsg(msg2); });
                    }
                    else if (msg1 != null && msg2 == null)
                    {
                        //只有一条消息,就直接执行
                        ProcessMsg(msg1);
                    }
                    else if (msg1 == null && msg2 != null)
                    {
                        //只有一条消息,就直接执行
                        ProcessMsg(msg2);
                    }
#else
                    NetWorkMsg msg = _msgQueue.Dequeue();
                    if (msg == null) //直到消息取尽之前都不停的处理
                    {
                        break;
                    }
                    float waitTime = (DateTime.Now.Ticks - msg.timeTickCreat) / 10000;//毫秒
                    if (waitTime > _warringWaitTime)
                    {
                        _warringWaitTime += 500;
                        DxDebug.LogWarning("DNServer.DoWork():NetWorkMsg等待处理时间过长!waitTime:" + waitTime);
                    }
                    else if ((_warringWaitTime - waitTime) > 500)
                    {
                        _warringWaitTime -= 500;
                    }

                    ProcessMsg(msg);
#endif
                    _cpuTime.WaitStart(); //时间分析计时
                }
            }
        }
Exemplo n.º 13
0
        private void DoConnect()
        {
            try
            {
                //DxDebug.LogConsole("DNClient.DoConnect():执行Connect...");
                //标记正在连接
                IsConnecting = true;

                Interlocked.Exchange(ref _snedingCount, 0);
                this.Clear();//清空数据

                if (_socketClient != null)
                {
                    //DxDebug.LogConsole("DNClient.DoConnect():断开原先连接!");
                    _socketClient.Disconnect();
                    _socketClient.Bind(_host, _port);//绑定新ip
                    _socketClient.Clear();
                    DxDebug.LogConsole("DNClient.DoConnect():-----------正在连接...");
                    _socketClient.Connect();
                    DxDebug.LogConsole("DNClient.DoConnect():-----------连接服务器成功!" + _host + ":" + _port);
                }
                else
                {
                    _socketClient = new SocketClient(_host, _port, _packet2);
                    if (_socketClient == null)
                    {
                        DxDebug.LogError("DNClient.DoConnect():-----------连接服务器失败!_socketClient对象未能创建成功。");
                        return;
                    }
                    _socketClient.EventReceive += OnReceive; //加入接收事件
                    _socketClient.EventSend    += OnSend;    //加入发送事件
                    _socketClient.EventError   += OnError;   //加入错误事件
                    DxDebug.LogConsole("DNClient.DoConnect():-----------正在连接...");
                    _socketClient.Connect();
                    DxDebug.LogConsole("DNClient.DoConnect():-----------连接服务器成功!" + _host + ":" + _port);
                }

                if (EventConnectSuccess != null)
                {
                    try { EventConnectSuccess(this); }//事件类型:ConnectError
                    catch (Exception e) { DxDebug.LogError("DNClient.DoConnect():执行EventError事件异常:" + e.Message); }
                }
            }
            catch (Exception e)
            {
                DxDebug.LogError("DNClient.DoConnect():-----------连接服务器失败!: " + e.Message);

                if (EventError != null)
                {
                    try { EventError(this, EventType.ConnectError, e); }//事件类型:ConnectError
                    catch (Exception e2) { DxDebug.LogError("DNClient.DoConnect():执行EventError事件异常:" + e2.Message); }
                }
            }
            //标记已经结束了连接
            IsConnecting = false;
        }
Exemplo n.º 14
0
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            IsInited = false;

            try
            {   //最先去把线程关了
                if (_workThread != null && _workThread.IsAlive)
                {
                    DxDebug.LogConsole("DNClient.Dispose():_workThread.Abort()线程中断!");
                    _workThread.Abort();
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.Dispose(): _workThread.Abort()异常" + e.Message);
            }
            finally
            {
                _workThread = null;
            }

            try
            {
                if (disposing)
                {
                    // 清理托管资源
                    _msgQueue.Clear();
                    _msgPool.Clear();

                    _msgQueue = null;
                    _msgPool  = null;
                }
                // 清理非托管资源
                _packet2.Clear();
                _msgSemaphore.Close();
                _msgSemaphore = null;
                if (_socketClient != null)
                {
                    _socketClient.Dispose();
                    _socketClient = null;
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.Dispose():释放异常" + e.Message);
            }
            //让类型知道自己已经被释放
            _disposed = true;

            IsConnecting = false;
        }
Exemplo n.º 15
0
        /// <summary>
        /// 连接服务器,输入IP和端口号。会强制重新初始化整个类,这样起到底层重启的作用。
        /// </summary>
        /// <param name="host">主机IP</param>
        /// <param name="port">端口号</param>
        public void Connect(string host, int port)
        {
            try
            {
                DxDebug.LogConsole("DNClient.Connect():连接服务器 主机:" + host + "  端口:" + port);

                //标记正在连接
                IsConnecting = true;

                //if (_disposed)
                //{
                //    DxDebug.LogConsole("DNClient.Connect():这个类对象是被释放状态,重新初始化");
                Init();
                //}

                //进行一次连接的时候,把消息队列清空
                Clear();

                Interlocked.Exchange(ref this._host, host); //给类成员赋值
                Interlocked.Exchange(ref this._port, port); //给类成员赋值

                NetWorkMsg msg = _msgPool.Dequeue();
                if (msg == null)
                {
                    msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Connect);
                }
                else
                {
                    msg.Reset(NetWorkMsg.Tpye.C_Connect);
                }
                AddMessage(msg);

                LastMsgReceTickTime = DateTime.Now.Ticks;
                LastMsgSendTickTime = DateTime.Now.Ticks;
            }
            catch (Exception e)
            {
                IsConnecting = false;//连接失败了
                DxDebug.LogError("DNClient.Connect():异常:" + e.Message);

                if (EventError != null)
                {
                    try
                    {
                        EventError(this, EventType.ConnectError, e);//事件类型:ConnectError
                    }
                    catch (Exception e2)
                    {
                        DxDebug.LogWarning("DNClient.Connect():执行EventError事件异常:" + e2.Message);
                    }
                }

                Dispose();//释放
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// 线程的工作函数
        /// </summary>
        private void DoWork()
        {
            DxDebug.LogConsole("WorkThread.DoWork():工作线程启动!");

            while (_isRun)
            {
                IWorkMsg msg = null;
                try
                {
                    //记录线程空闲
                    RecThreadStatus(Thread.CurrentThread.ManagedThreadId, false);

                    _msgSemaphore.WaitOne();
                    Interlocked.Decrement(ref _curSemCount);

                    //记录线程开始工作
                    RecThreadStatus(Thread.CurrentThread.ManagedThreadId, true);

                    while (true)
                    {
                        msg = _msgQueue.Dequeue();
                        if (msg != null)
                        {
                            //递增计数
                            Interlocked.Increment(ref _procMsgCount);
                            try
                            {
                                //取一条消息进行执行
                                msg.DoWork();
                            }
                            catch (Exception e)
                            {
                                DxDebug.LogWarning("WorkThread.DoWork():执行msg异常:" + msg.Name + "异常信息:" + e.Message);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (msg != null)
                    {
                        DxDebug.LogError("WorkThread.DoWork():异常:" + msg.Name + "异常信息:" + e.Message);
                    }
                    else
                    {
                        DxDebug.LogError("WorkThread.DoWork():异常:目前IWorkMsg为null(可能空闲),异常信息:" + e.Message);
                    }
                }
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// 启动服务器
        /// </summary>
        /// <param name="hostName">服务器的ip</param>
        /// <param name="port">本机的服务器端口</param>
        internal void Start(string hostName, int port)
        {
            try
            {
                _isStarted = false;
                IPAddress address = IPAddress.Any;
                if (hostName == "Any")
                {
                    address = IPAddress.Any;
                }
                else if (Regex.IsMatch(hostName, @"\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}"))
                {
                    byte[] ipadr = new byte[4];

                    MatchCollection ms = Regex.Matches(hostName, @"\d{1,3}");
                    for (int i = 0; i < ms.Count; i++)
                    {
                        ipadr[i] = Convert.ToByte(hostName.Substring(ms[i].Index, ms[i].Length));
                    }
                    address = new IPAddress(ipadr);
                }
                else
                {
                    IPHostEntry host        = Dns.GetHostEntry(hostName);
                    IPAddress[] addressList = host.AddressList;
                    address = addressList[addressList.Length - 1];
                }
                IPEndPoint localEndPoint = new IPEndPoint(address, port);
                DxDebug.LogConsole("SocketListener.Start():尝试启动服务器 " + address + ":" + port);

                //创建一个监听Socket
                this._listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                this._listenSocket.ReceiveBufferSize = this._bufferSize;
                this._listenSocket.SendBufferSize    = this._bufferSize;

                if (localEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    this._listenSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false);
                    this._listenSocket.Bind(new IPEndPoint(IPAddress.IPv6Any, localEndPoint.Port));
                }
                else
                {
                    this._listenSocket.Bind(localEndPoint);
                }
                this._listenSocket.Listen(2); //最大挂起数
                this.StartAccept2();

                _isStarted = true;//服务器启动成功
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("SocketListener.Start():Start函数错误:" + e.Message);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// 初始化并且开始,如果调用了果了Dispose,那么可以重新调用这个函数再次开始。
        /// </summary>
        public void Start()
        {
            if (disposed == false)
            {
                Dispose();
            }
            _timer = new Timer(new TimerCallback(OnTimerTick));
            _timer.Change(250, KICK_TIME);

            _count3S = 0;
            DxDebug.LogConsole("ClientTimer.Init():ClientTimer启动!");
        }
Exemplo n.º 19
0
        /// <summary>
        /// 这个对象的Close()函数会调用该函数
        /// </summary>
        public void Dispose()
        {
            DxDebug.LogWarning("DNServer.Dispose():进入了Dispose.");
            if (_workThread != null)
            {
                for (int i = 0; i < _workThread.Length; i++)
                {
                    DxDebug.LogConsole("DNServer.Dispose():[" + _workThread[i].Name + "].IsAlive 为:" + _workThread[i].IsAlive);
                }
            }

            Dispose(true);
        }
Exemplo n.º 20
0
        /// <summary>
        /// 工作线程启动
        /// </summary>
        public void Start()
        {
            try
            {
                //标记线程可以运行
                _isRun = true;

                if (_disposed)
                {
                    //标记自己已经有了资源申请
                    _disposed = false;
                    try
                    {
                        DxDebug.LogConsole("WorkThread.Start():这个类对象经被释放或刚刚构造,重新初始化");
                        _msgQueue     = new DQueue <IWorkMsg>(MSG_QUEUE_CAPACITY, _initMsgQueueSize);
                        _msgSemaphore = new Semaphore(0, 64);//由于AddMessage的改动,这里只需要是随便一个数既可

                        _isWorking    = new bool[_threadCount];
                        _lastWorkTime = new long[_threadCount];
                        _workThreadID = new int[_threadCount];

                        _workThread = new Thread[_threadCount];
                        for (int i = 0; i < _threadCount; i++)
                        {
                            _workThread[i] = new Thread(DoWork);
                            _workThread[i].IsBackground = true;
                            //工作线程的优先级(影响不大)
                            _workThread[i].Priority = ThreadPriority.Highest;
                            _workThread[i].Name     = name + i;
                            //记录线程ID
                            _workThreadID[i] = _workThread[i].ManagedThreadId;
                            _workThread[i].Start(); //启动线程
                        }
                    }
                    catch (Exception e)
                    {
                        DxDebug.LogError("WorkThread.Start():构造失败!异常:" + e.Message);
                        Dispose();
                    }
                }
                else
                {
                    Dispose();
                    Start();
                }
            }
            catch (Exception e)
            {
                DxDebug.LogError("WorkThread.Start():异常:" + e.Message);
            }
        }
Exemplo n.º 21
0
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            try
            {
                DxDebug.LogConsole("WorkThread.DoWork():工作线程关闭!");
                _isRun = false;

                //最先去把线程关了
                for (int i = 0; i < _threadCount; i++)
                {
                    //把线程关了
                    if (_workThread[i] != null && _workThread[i].IsAlive)
                    {
                        try
                        {
                            _workThread[i].Abort();
                        }
                        catch (Exception e)
                        {
                            DxDebug.LogWarning("WorkThread.Dispose():异常 _workThread[" + i + "].Abort();" + e.Message);
                        }
                    }
                }

                if (disposing)
                {
                    // 清理托管资源
                    if (_msgQueue != null)
                    {
                        _msgQueue.Clear();
                    }
                }
                // 清理非托管资源
                if (_msgSemaphore != null)
                {
                    _msgSemaphore.Close();
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("WorkThread.Dispose():释放异常" + e.Message);
            }
            //让类型知道自己已经被释放
            _disposed = true;
        }
Exemplo n.º 22
0
        /// <summary>
        /// 检查用户是否其实已经离线,在OnTimerTick函数里调用
        /// </summary>
        private void CheckOffLineAndSend()
        {
            _countHeartBeatCheckTime += KICK_TIME;
            if (_countHeartBeatCheckTime >= Config.HeartBeatCheckTime) //15秒*1
            {
                Interlocked.Exchange(ref _countHeartBeatCheckTime, 0); //这里要立马置零,防止后面的代码执行的过久,再次进入kick

                Token[] tokens = TokenManager.GetInstance().GetAllToken();
                if (tokens != null)
                {
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        Token token = tokens[i];
                        if (token.LastMsgReceTickTime < _checkTickTime) //如果从上次的进入这里的时间之后一直都没有收到消息
                        {
                            DxDebug.LogConsole("ServerTimer.CheckOffLine():一个用户长时间没有收到心跳包,被删除!");

                            TokenManager.GetInstance().DeleteToken(token.ID, TokenErrorType.HeartBeatTimeout);//删除这个用户
                        }
                    }
                }

                _checkTickTime = DateTime.Now.Ticks;
            }

            _countHeartBeatSendTime += KICK_TIME;
            if (_countHeartBeatSendTime >= Config.HeartBeatSendTime)                      //5秒进一次
            {
                Interlocked.Exchange(ref _countHeartBeatSendTime, 0);                     //这里要立马置零,防止后面的代码执行的过久,再次进入kick

                long subTimeTick = DateTime.Now.Ticks - 10000 * Config.HeartBeatSendTime; //计算得到的门限时间

                Token[] tokens = TokenManager.GetInstance().GetAllToken();
                if (tokens != null)
                {
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        Token token = tokens[i];
                        if (token.disposed == false && token.LastMsgSendTickTime < subTimeTick) //如果从上次的进入这里的时间之后一直都没有发消息
                        {
                            //应该发送一条心跳包
                            token.AddSendData(Config.HeartBeatData, 0, Config.HeartBeatData.Length);
                        }
                    }
                    DNServer.GetInstance().SendAll();//整体发送
                }
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// 设置工作目录路径,如果传入空则表示工作路径为当前程序运行路径.通常来说在运行之前都应该指定一个目录
        /// </summary>
        public bool SetDirCache(string dir)
        {
            try
            {
                DxDebug.LogConsole("DNServer.SetDirCache():尝试设置工作文件夹路径 dir = " + dir);

                if (String.IsNullOrEmpty(dir))
                {
                    dirCache = Directory.GetCurrentDirectory();
                    DxDebug.LogConsole("DNServer.SetDirCache():输入路径为空,所以设置文件夹为" + dirCache);
                }
                else
                {
                    dirCache = dir;              //赋值
                }
                if (!Directory.Exists(dirCache)) //如果这个目录不存在,那么就尝试创建一下这个目录
                {
                    DxDebug.LogConsole("DNServer.SetDirCache():文件夹不存在,创建文件夹...");
                    Directory.CreateDirectory(dirCache);
                }
                string testfile = System.IO.Path.Combine(dirCache, "dirtestFile_");

                DxDebug.LogConsole("DNServer.SetDirCache():进行文件读写测试...");
                FileStream fs = File.Create(testfile); //创建一下试试
                fs.WriteByte(0xff);
                fs.Flush();
                fs.Close();
                fs = File.Open(testfile, FileMode.Open);
                if (fs.ReadByte() != 0xff)
                {
                    dirCache = null;
                    return(false);
                }
                fs.Close();
                File.Delete(testfile);
                DxDebug.LogConsole("DNClient.SetDirCache():进行文件读写测试成功");

                return(true);//如果允许到这里都没有错误,那么说明这个目录可以正常使用
            }
            catch (Exception e)
            {
                DxDebug.LogError("DNServer.SetDirCache():设置工作文件夹失败! " + e.Message);
            }

            dirCache = null;

            return(false);
        }
Exemplo n.º 24
0
        /// <summary>
        /// 初始化并且开始,如果调用了果了Dispose,那么可以重新调用这个函数再次开始。
        /// 如果已经初始化,那么不会执行。
        /// </summary>
        public void Start()
        {
            //这里不要强制释放了
            //if (disposed == false)
            //{
            //    Dispose();
            //}
            if (disposed)
            {
                _timer = new Timer(new TimerCallback(OnTimerTick));
                _timer.Change(250, KICK_TIME);
                _checkTickTime = DateTime.Now.Ticks;

                DxDebug.LogConsole("ServerTimer.Init():ServerTimer启动!");
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// 异步的关闭socket和线程,会在消息队列中执行完这个消息之前的所有消息后,才会执行。
        /// </summary>
        public void Close()
        {
            DxDebug.LogConsole("DNClient.Close():进入了close函数!");

            NetWorkMsg msg = _msgPool.Dequeue();

            if (msg == null)
            {
                msg = new NetWorkMsg(NetWorkMsg.Tpye.C_AsynClose);
            }
            else
            {
                msg.Reset(NetWorkMsg.Tpye.C_AsynClose);
            }
            AddMessage(msg);
        }
Exemplo n.º 26
0
        private void OnReceive()
        {
            if (this._isDebugLog)
            {
                DxDebug.LogConsole("-----------EventHandler:进入了OnReceive回调!");
            }

            NetWorkMsg msg = _msgPool.Dequeue();

            if (msg == null)
            {
                msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Receive);
            }
            else
            {
                msg.Reset(NetWorkMsg.Tpye.C_Receive);
            }
            AddMessage(msg);
        }
Exemplo n.º 27
0
        /// <summary>
        /// 发生了错误,通常是断开连接了
        /// </summary>
        /// <param name="e"></param>
        private void ProcessError(SocketAsyncEventArgs e)
        {
            try
            {
                Token      token   = e.UserToken as Token;
                IPEndPoint localEp = token.socket.LocalEndPoint as IPEndPoint;

                DxDebug.LogConsole(string.Format("SocketListener.ProcessError():SocketError:{0}  IP:{1}  上次操作:{2}.", e.SocketError, localEp, e.LastOperation));
                TokenManager.GetInstance().DeleteToken(token.ID, e.SocketError);
                //  token.Close();//执行关闭
                if (EventError != null)// 执行事件
                {
                    EventError(token, e.SocketError);
                }
            }
            catch (Exception ex)
            {
                DxDebug.LogWarning("SocketListener.ProcessError():异常:" + ex.Message);
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// 在定时器中调用的函数
        /// </summary>
        private void OnUpdate()
        {
            int cur1sReceive      = CountReceive - _lastCountReceive;
            int cur1sSend         = CountSend - _lastCountSend;
            int cur1sReceiveBytes = CountReceiveBytes - _lastCountReceiveBytes;
            int cur1sSendBytes    = CountSendBytes - _lastCountSendBytes;

            _lastCountReceive      = CountReceive;
            _lastCountSend         = CountSend;
            _lastCountReceiveBytes = CountReceiveBytes;
            _lastCountSendBytes    = CountSendBytes;

            CountReceive10s.EnqueueMaxLimit(cur1sReceive);           //添加这一秒的结果到末尾
            CountSend10s.EnqueueMaxLimit(cur1sSend);                 //添加这一秒的结果到末尾
            CountReceiveBytes10s.EnqueueMaxLimit(cur1sReceiveBytes); //添加这一秒的结果到末尾
            CountSendBytes10s.EnqueueMaxLimit(cur1sSendBytes);       //添加这一秒的结果到末尾

            if (isPrintCur1s && _dnServer.IsStarted)                 //如果设置了打印这一秒,并且服务器在工作
            {
                DxDebug.LogConsole(String.Format("ServerStatus.OnUpdate():一秒内接收/发送:{0}/{2}条,总{4}/{5}条,消息队列长{6} ,{1:F1}/{3:F1}kB.",
                                                 cur1sReceive, cur1sReceiveBytes / 1000.0f, cur1sSend, cur1sSendBytes / 1000.0f, CountReceive, CountSend, _dnServer.msgQueueLength));
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// 开始接受客户端的Accept,使用一组SocketAsyncEventArgs
        /// </summary>
        private void StartAccept2()
        {
            //lock (_lockAccept)//这个加锁没有解决问题
            //{
            try
            {
                if (_acceptEventArgs == null)
                {
                    _acceptEventArgs = new SocketAsyncEventArgs[2];
                    for (int i = 0; i < _acceptEventArgs.Length; i++)
                    {
                        _acceptEventArgs[i]            = new SocketAsyncEventArgs();
                        _acceptEventArgs[i].Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted);
                    }
                }
                for (int i = 0; i < _acceptEventArgs.Length; i++)
                {
                    _acceptEventArgs[i].AcceptSocket = null;   // 必须要先清掉Socket
                }

                DxDebug.LogConsole("SocketListener.StartAccept2():服务器开始接收认证!");
                for (int i = 0; i < _acceptEventArgs.Length; i++)
                {
                    //开始异步接收认证
                    if (!_listenSocket.AcceptAsync(_acceptEventArgs[i]))
                    {
                        this.ProcessAccept(_acceptEventArgs[i]);
                    }
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("SocketListener.StartAccept2():异常:" + e.Message);
                throw;
            }
            //}
        }
Exemplo n.º 30
0
        private void DoWork()
        {
            try
            {
                DxDebug.LogConsole("DNClient.DoWork():-----------通信线程启动!");
                while (true)
                {
                    Interlocked.Exchange(ref _isThreadWorking, 0);//标记当前线程已经停止工作

                    _msgSemaphore.WaitOne();
                    Interlocked.Decrement(ref _curSemCount);       //递减信号量计数

                    Interlocked.Exchange(ref _isThreadWorking, 1); //标记当前线程已经正在执行工作

                    //_cpuTime.WorkStart(); //时间分析计时

                    while (true)
                    {
                        NetWorkMsg msg = _msgQueue.Dequeue();
                        if (msg == null)
                        {
                            break;
                        }
                        float waitTime = (DateTime.Now.Ticks - msg.timeTickCreat) / 10000;//毫秒
                        if (waitTime > _warringWaitTime)
                        {
                            _warringWaitTime += 500;
                            DxDebug.LogWarning("DNClient.DoWork():NetWorkMsg等待处理时间过长!waitTime:" + waitTime);
                        }
                        else if ((_warringWaitTime - waitTime) > 500)
                        {
                            _warringWaitTime -= 500;
                        }

                        if (msg != null)
                        {
                            switch (msg.type)
                            {
                            case NetWorkMsg.Tpye.C_Connect:
                                DoConnect();
                                break;

                            case NetWorkMsg.Tpye.C_Send:
                                DoSend(msg);
                                break;

                            case NetWorkMsg.Tpye.C_Receive:
                                DoReceive();
                                break;

                            case NetWorkMsg.Tpye.C_AsynClose:
                                DoClose();
                                _workThread = null; //把这个成员置为空
                                return;             //执行完就结束了整个线程函数

                            default:

                                break;
                            }
                            //用过的消息放回池里
                            _msgPool.EnqueueMaxLimit(msg);
                        }
                        else
                        {
                            // _cpuTime.Calculate();//空闲的话就计算一下
                        }
                        //long costTime = _cpuTime.WaitStart(); //时间分析计时
                    }
                }
            }
            catch (Exception e)
            {
                DxDebug.LogError("DNClient.DoWork():异常:通信线程执行异常! " + e.Message);
            }
        }