예제 #1
0
        /// <summary>
        /// 检查队列里是否有要发送的数据,如果有则进行发送处理
        /// </summary>
        public void PeekSend()
        {
            lock (m_PendingBuffer)
            {
                if (isSending || m_PendingBuffer.Count == 0)
                {
                    return;
                }

                //  TODO 这里要不要考虑进行并报发送处理
                isSending = true;

                if (m_PendingBuffer.Count > 1)
                {
                    //   2 个包以上,进行拼包后再发送
                    var buffs = m_PendingBuffer.ToArray();
                    m_PendingBuffer.Clear();

                    int offSet = 0;
                    foreach (var b in buffs)
                    {
                        offSet += b.Length;
                    }

                    DogBuffer sendBuff;

                    if (offSet < 4000)
                    {
                        sendBuff = DogBuffer.GetFromPool4K();
                    }
                    else
                    {
                        sendBuff = DogBuffer.GetFromPool32K();
                    }

                    foreach (var buff in buffs)
                    {
                        Buffer.BlockCopy(buff.Bytes, 0, sendBuff.Bytes, sendBuff.Length, buff.Length);
                        sendBuff.Length += buff.Length;
                        buff.Release();
                    }

                    SendEventArgs.UserToken = sendBuff;
                    SendEventArgs.SetBuffer(sendBuff.Bytes, 0, sendBuff.Length);
                    Socket.SendAsync(SendEventArgs);
                }
                else
                {
                    DogBuffer buff;
                    buff = m_PendingBuffer.Dequeue();
                    SendEventArgs.UserToken = buff;
                    SendEventArgs.SetBuffer(buff.Bytes, 0, buff.Length);
                    Socket.SendAsync(SendEventArgs);
                }
            }
        }
예제 #2
0
 internal static void ReleaseToPool(DogBuffer bufff)
 {
     bufff.Length = 0;
     if (bufff.BuffSizeType == DogBufferType._4K)
     {
         s_pools.ReleaseContent(bufff);
     }
     else if (bufff.BuffSizeType == DogBufferType._32K)
     {
         s_pools32K.ReleaseContent(bufff as DogBuffer32K);
     }
 }
예제 #3
0
        /// <summary>
        /// 重新异步开始接受数据
        /// </summary>
        internal void SyncRecvData()
        {
            if (Socket == null || !Socket.Connected)
            {
                return;
            }

            var buff = DogBuffer.GetFromPool4K();

            RecvBuffer = buff;
            ReceiveEventArgs.SetBuffer(buff.Bytes, 0, buff.Bytes.Length);
            Socket.ReceiveAsync(ReceiveEventArgs);
        }
예제 #4
0
 internal static void ReleaseToPool(DogBuffer bufff)
 {
     //lock (lockOjb)
     {
         bufff.Length = 0;
         if (bufff.BuffSizeType == DogBufferType._4K)
         {
             s_pools.ReleaseContent(bufff);
         }
         else if (bufff.BuffSizeType == DogBufferType._32K)
         {
             var _32buf = bufff as DogBuffer32K;
             s_pools32K.ReleaseContent(_32buf);
         }
     }
 }
예제 #5
0
        /// <summary>
        /// 客户端的session的初始化,必须有一个对应的网络连接
        /// </summary>
        /// <param name="socket"></param>
        internal ClientSession(Socket socket)
        {
            if (socket == null)
            {
                throw new ArgumentNullException("socket", "ClientSession create socket don't null.");
            }

            Socket                   = socket;
            SendEventArgs            = new SocketAsyncEventArgs();
            SendEventArgs.Completed += OnSendCompleted;

            RecvBuffer       = new DogBuffer();
            ReceiveEventArgs = new SocketAsyncEventArgs();
            ReceiveEventArgs.SetBuffer(RecvBuffer.Bytes, 0, RecvBuffer.Bytes.Length);

            ConnectTime = OneServer.NowTime;
        }
예제 #6
0
        /// <summary>
        /// 向客户端发送数据
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="isSendNow">是否立即发送</param>
        public void SendPackage(DogBuffer buff, bool isSendNow = true)
        {
            if (Socket == null || !Socket.Connected)
            {
                return;
            }

            buff.Use();

            lock (m_PendingBuffer)
            {
                m_PendingBuffer.Enqueue(buff);
            }

            if (isSendNow)
            {
                PeekSend();
            }
        }
예제 #7
0
        /// <summary>
        /// 抛出收到数据事件
        /// </summary>
        /// <param name="session"></param>
        /// <param name="buff"></param>
        private void NotifySocketRecvEvent(ClientSession <T> session, DogBuffer buff)
        {
            var recvTemp = SocketRecv;

            if (recvTemp != null)
            {
                var ev = m_recvEventArgsPool.AcquireContent();
                ev.Buffer  = buff;
                ev.Session = session;
                try
                {
                    recvTemp(this, ev);
                }
                catch (Exception ex)
                {
                    Logs.Error("OnSocketRecv event error.", ex);
                }

                ev.Buffer  = null;
                ev.Session = null;
                m_recvEventArgsPool.ReleaseContent(ev);
            }
        }
예제 #8
0
        /// <summary>
        /// 向客户端发送数据
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="isSendNow">是否立即发送</param>
        public void SendPackage(DogBuffer buff, bool isSendNow = true)
        {
            if (Socket == null || !Socket.Connected)
            {
                return;
            }

            if (buff.Length == 0)
            {
                throw new Exception("buff lenght is zero.");
            }

            buff.Use();

            lock (m_PendingBuffer)
            {
                m_PendingBuffer.Enqueue(buff);
            }

            if (isSendNow)
            {
                PeekSend();
            }
        }
예제 #9
0
 internal static void ReleaseToPool(DogBuffer bufff)
 {
     //lock (lockOjb)
     {
         bufff.Length = 0;
         if (bufff.BuffSizeType == DogBufferType._4K)
             s_pools.ReleaseContent(bufff);
         else if (bufff.BuffSizeType == DogBufferType._32K)
         {
             var _32buf = bufff as DogBuffer32K;
             s_pools32K.ReleaseContent(_32buf);
         }
     }
 }
예제 #10
0
파일: Program.cs 프로젝트: RainsSoft/DogSE
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs<Session> e)
        {
            var session = e.Session.Data;
            session.RQ.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var packetlen = session.RQ.GetPacketLength();
            if (packetlen > 1024*64)
            {
                session.Client.CloseSocket();
                return;
            }

            while (packetlen >= session.RQ.Length)
            {
                var dogBuffer = new DogBuffer();
                session.RQ.Dequeue(dogBuffer.Bytes, 0, packetlen);

                var reader = new PacketReader();
                reader.SetBuffer(dogBuffer);

                var pid = (OpCode)reader.GetPacketID();

                switch (pid)
                {
                    case OpCode.Login:
                    {
                        var userName = reader.ReadUTF8String();
                        var pwd = reader.ReadUTF8String();

                        if (string.IsNullOrEmpty(userName))
                        {
                            Logs.Error("连接的用户名是空");
                            session.Client.CloseSocket();
                        }

                        if (pwd != "123")
                        {
                            Logs.Error("用户名 {0} 速度的密码错误", userName);
                            var writer = new PacketWriter();
                            writer.SetNetCode((ushort) OpCode.LoginResult);
                            writer.Write(1); //  0表示登录成功 1表示密码错误
                            session.Client.SendPackage(writer.GetBuffer());
                            return;
                        }

                        //  如果玩家之前登录过,则把之前的客户端踢下线
                        var exists = sessions.FirstOrDefault(o => o.Name == userName);
                        if (exists != null)
                        {
                            exists.IsLogin = false;
                            sessions.Remove(exists);
                            exists.Client.CloseSocket();
                        }

                        //  登录完成
                        session.IsLogin = true;
                        nologinSessions.Remove(session);
                        sessions.Add(session);

                        session.Name = userName;
                        session.Pwd = pwd;
                        var writer2 = new PacketWriter();
                        writer2.SetNetCode((ushort) OpCode.LoginResult);
                        writer2.Write(0); //  0表示登录成功 1表示密码错误
                        session.Client.SendPackage(writer2.GetBuffer());
                    }
                        break;
                    case OpCode.SendMessage:
                    {
                        var message = reader.ReadUTF8String();
                        if (string.IsNullOrEmpty(message))
                        {
                            //  空消息
                            return;
                        }

                        //  广播给所有在线的用户
                        var writer = new PacketWriter();
                        writer.SetNetCode((ushort) OpCode.RecvMessage);
                        foreach (var ss in sessions)
                        {
                            ss.Client.SendPackage(writer.GetBuffer());
                        }
                    }
                        break;
                    case OpCode.SendPriviteMessage:
                    {
                        var userName = reader.ReadUTF8String();
                        var message = reader.ReadUTF8String();

                        if (message == null)
                            return;

                        var target = sessions.FirstOrDefault(o => o.Name == userName);
                        if (target == null)
                            return;

                        var writer = new PacketWriter();
                        writer.SetNetCode((ushort) OpCode.RecvPrivateMessage);
                        writer.WriteUTF8Null(session.Name);
                        writer.WriteUTF8Null(message);

                        target.Client.SendPackage(writer.GetBuffer());
                    }
                        break;
                    default:
                        Logs.Error("未知消息ID {0}", (int) pid);
                        break;
                }

                packetlen = session.RQ.GetPacketLength();
            }
        }
예제 #11
0
파일: Program.cs 프로젝트: RainsSoft/DogSE
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs<Session> e)
        {
            var session = e.Session.Data;
            session.RQ.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var packetlen = session.RQ.GetPacketLength();
            while (packetlen >= session.RQ.Length)
            {
                var dogBuffer = new DogBuffer();
                session.RQ.Dequeue(dogBuffer.Bytes, 0, packetlen);

                var reader = new PacketReader();
                reader.SetBuffer(dogBuffer);

                var pid = reader.GetPacketID();
                var handler = packetHandlersManager.GetHandler(pid);
                if (handler == null)
                {
                    Logs.Error("未知消息ID {0}", pid);
                }
                else
                {
                    //  网络的消息包都会压入任务队列里等待执行
                    taskManager.AppendTask(session, handler, reader);
                }

                packetlen = session.RQ.GetPacketLength();
            }
        }
예제 #12
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="buffer"></param>
 public PacketReader(DogBuffer buffer)
 {
     m_Data  = buffer.Bytes;
     m_Size  = buffer.Length;
     m_Index = 4 + 2;    // 包头的长度和消息码长度
 }
예제 #13
0
 /// <summary>
 /// 释放资源
 /// </summary>
 public void Dispose()
 {
     if (m_buffer != null)
     {
         var t = m_buffer;
         m_buffer = null;
         t.Release();
     }
 }
예제 #14
0
파일: Program.cs 프로젝트: RainsSoft/DogSE
        /// <summary>
        /// 收到Socket数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnSocketRecv(object sender, SocketRecvEventArgs<Session> e)
        {
            var session = e.Session.Data;
            session.RQ.Enqueue(e.Buffer.Bytes, 0, e.Buffer.Length);

            var packetlen = session.RQ.GetPacketLength();
            while (packetlen >= session.RQ.Length)
            {
                var dogBuffer = new DogBuffer();
                session.RQ.Dequeue(dogBuffer.Bytes, 0, packetlen);

                var reader = new PacketReader();
                reader.SetBuffer(dogBuffer);

                /*
                var pid = (OpCode)reader.GetPacketID();

                switch (pid)
                {
                    case OpCode.Login:
                        OnLogin(session, reader);
                        break;
                    case OpCode.SendMessage:
                        OnSendMessage(session, reader);
                        break;
                    case OpCode.SendPriviteMessage:
                        OnSendPrivateMessage(session, reader);
                        break;
                    default:
                        Logs.Error("未知消息ID {0}", (int)pid);
                        break;
                }
                */

                var pid = reader.GetPacketID();
                var handler = packetHandlersManager.GetHandler(pid);
                if (handler == null)
                {
                    Logs.Error("未知消息ID {0}", pid);
                }
                else
                {
                    handler.OnReceive(session, reader);
                }

                packetlen = session.RQ.GetPacketLength();
            }
        }
예제 #15
0
파일: DogBuffer.cs 프로젝트: Jimlan/DogSE
 internal static void ReleaseToPool(DogBuffer bufff)
 {
     bufff.Length = 0;
     if (bufff.BuffSizeType == DogBufferType._4K)
         s_pools.ReleaseContent(bufff);
     else if (bufff.BuffSizeType == DogBufferType._32K)
         s_pools32K.ReleaseContent(bufff as DogBuffer32K);
 }