Example #1
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);
            }
        }
Example #2
0
        /// <summary>
        /// 添加一个工作任务到消息队列,提供给这些线程来处理
        /// </summary>
        /// <param name="msg"></param>
        public void AddMessage(IWorkMsg msg)
        {
            try
            {
                if (_msgQueue.EnqueueMaxLimit(msg))
                {
                    if (_curSemCount < 1)//如果当前的信号量剩余不多的时候
                    {
                        Interlocked.Increment(ref _curSemCount);
                        _msgSemaphore.Release();// 释放信号量
                    }
                }
                else
                {
                    DxDebug.LogWarning("WorkThread.AddMessage():大于工作线程的能力了,丢弃了一条消息!");
                }

                if (_msgQueuePeakLength < _msgQueue.Count)
                {
                    _msgQueuePeakLength = _msgQueue.Count;//记录当前的峰值长度
                }
            }
            catch (SemaphoreFullException)
            {
                DxDebug.LogError("WorkThread.AddMessage():大于工作线程的能力了:");

                throw;
            }
            catch (Exception e)
            {
                DxDebug.LogError("WorkThread.AddMessage():异常:" + e.Message);
                throw;
            }
        }
Example #3
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;
        }
Example #4
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();//释放
            }
        }
Example #5
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);
                    }
                }
            }
        }
Example #6
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);
            }
        }
Example #7
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);
        }
Example #8
0
        /// <summary>
        /// 加入一条要执行的消息,如果加入的过快而无法发送,则将产生信号量溢出异常,表明当前发送数据频率要大于系统能力
        /// </summary>
        /// <param name="msg"></param>
        internal void AddMessage(NetWorkMsg msg)
        {
            try
            {
                if (msg != null)
                {
                    _msgQueue.Enqueue(msg);
                }
                if (_curSemCount < 1) //信号量剩余较少的时候才去释放信号量
                {
                    Interlocked.Increment(ref _curSemCount);
                    _msgSemaphore.Release();
                }
            }
            catch (SemaphoreFullException)
            {
                //当前发送数据频率要大于系统能力,可尝试增加消息队列长度
                string msgtype = "";
                switch (msg.type)
                {
                case NetWorkMsg.Tpye.S_Start:
                    msgtype = "S_Start";
                    break;

                case NetWorkMsg.Tpye.S_Send:
                    msgtype = "S_Send";
                    break;

                case NetWorkMsg.Tpye.S_Receive:
                    msgtype = "S_Receive";
                    break;

                default:
                    break;
                }
                DxDebug.LogError("DNServer.AddMessage():大于系统能力,当前最后一条:" + msgtype);
                throw;
            }
            catch (Exception e)
            {
                DxDebug.LogError("DNServer.AddMessage():*****发生错误! " + e.Message);
                throw;
            }
        }
Example #9
0
        /// <summary>
        /// 初始化这个对象,会创建工作线程
        /// </summary>
        private void Init()
        {
            try
            {
                //if (!_disposed)//强制释放一遍
                //{
                //    DxDebug.LogConsole("DNClient.Init():释放资源");
                //    Dispose();
                //}
                if (_msgQueue == null)
                {
                    _msgQueue = new DQueue <NetWorkMsg>(int.MaxValue, 256);
                }
                if (_msgPool == null)
                {
                    _msgPool = new DQueue <NetWorkMsg>(int.MaxValue, 256);
                }

                if (_msgSemaphore == null)
                {
                    _msgSemaphore = new Semaphore(0, 4);
                    Interlocked.Exchange(ref _curSemCount, 0);
                }

                if (_workThread == null)
                {
                    _workThread = new Thread(DoWork);
                    _workThread.IsBackground = true;

                    _workThread.Start(); //启动线程
                }

                _disposed = false;
                IsInited  = true;
            }
            catch (Exception e)
            {
                Dispose();
                DxDebug.LogError("DNClient.Init():异常:" + e.Message);
            }
        }
Example #10
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);
            }
        }
Example #11
0
        /// <summary>
        /// 加入一条要执行的消息,如果加入的过快而无法发送,则将产生信号量溢出异常,表明当前发送数据频率要大于系统能力
        /// </summary>
        /// <param name="msg"></param>
        internal void AddMessage(NetWorkMsg msg)
        {
            if (_disposed)
            {
                DxDebug.LogWarning("DNClient.AddMessage():DNClient对象已经被释放,不能再加入消息。msgType = " + msg.type.ToString());
                return;
            }
            try
            {
                DxDebug.Log("DNClient.AddMessage():向消息队列中添加消息");
                if (msg != null)
                {
                    _msgQueue.Enqueue(msg); //消息进队列
                }
                if (_curSemCount < 1)       //如果当前的信号量剩余不多的时候
                {
                    Interlocked.Increment(ref _curSemCount);
                    _msgSemaphore.Release();// 释放信号量
                }

                //发送数据队列长度为128则认为消息已经积攒较长
                if (_packet2.SendMsgCount > 128 && _isQueueFull == false)//MAX_SEND_DATA_QUEUE
                {
                    _isQueueFull = true;

                    if (EventSendQueueIsFull != null)
                    {
                        try
                        {
                            EventSendQueueIsFull(this);
                        }
                        catch (Exception e)
                        {
                            DxDebug.LogWarning("DNClient.AddMessage():执行事件EventMsgQueueIsFull异常:" + e.Message);
                        }
                    }
                    if (_isDebugLog)
                    {
                        DxDebug.LogWarning("DNClient.AddMessage():向消息队列中添加消息,发送队列长度较长:" + _packet2.SendMsgCount);
                    }
                }
                else if (_isQueueFull)//如果现在的状态是发送队列较长的状态,那么再去记录峰值长度
                {
                    if (_sendQueuePeakLength < _packet2.SendMsgCount)
                    {
                        _sendQueuePeakLength = _packet2.SendMsgCount;//记录当前的峰值长度
                    }
                }
            }
            catch (SemaphoreFullException)
            {
                //当前发送数据频率要大于系统能力,可尝试增加消息队列长度
                string msgtype = "";
                switch (msg.type)
                {
                case NetWorkMsg.Tpye.C_Connect:
                    msgtype = "C_Connect";
                    break;

                case NetWorkMsg.Tpye.C_Send:
                    msgtype = "C_Send";
                    break;

                case NetWorkMsg.Tpye.C_Receive:
                    msgtype = "C_Receive";
                    break;

                default:
                    break;
                }
                DxDebug.LogError("DNClient.AddMessage():大于系统能力,当前最后一条:" + msgtype);
                //throw;//这个throw还是应该去掉
                _msgPool.EnqueueMaxLimit(msg);
            }
            catch (Exception e)
            {
                DxDebug.LogError("DNClient.AddMessage():异常:" + e.Message);
                //throw;//这个throw还是应该去掉
                _msgPool.EnqueueMaxLimit(msg);
            }
        }