Ejemplo n.º 1
0
        public void HandleRecv(byte[] date, int offset, int length)
        {
            if (this.IsDisposed)
            {
                return;
            }

            this.IsConnected = true;

            Kcp.KcpInput(this.kcp, date, offset, length);
            this.Service.AddToUpdateNextTime(0, this.Id);

            while (true)
            {
                if (this.IsDisposed)
                {
                    break;
                }
                int n = Kcp.KcpPeeksize(this.kcp);
                if (n < 0)
                {
                    break;
                }
                if (n == 0)
                {
                    this.OnError((int)SocketError.NetworkReset);
                    break;
                }

                MemoryStream ms = MessageSerializeHelper.GetStream(n);

                ms.SetLength(n);
                ms.Seek(0, SeekOrigin.Begin);
                byte[] buffer = ms.GetBuffer();
                int    count  = Kcp.KcpRecv(this.kcp, buffer, n);
                if (n != count)
                {
                    break;
                }

                switch (this.Service.ServiceType)
                {
                case ServiceType.Inner:
                    ms.Seek(Packet.ActorIdLength + Packet.OpcodeLength, SeekOrigin.Begin);
                    break;

                case ServiceType.Outer:
                    ms.Seek(Packet.OpcodeLength, SeekOrigin.Begin);
                    break;
                }
                this.lastRecvTime = this.Service.TimeNow;
                this.OnRead(ms);
            }
        }
Ejemplo n.º 2
0
        public void Dispatch(Session session, MemoryStream memoryStream)
        {
            ushort opcode  = BitConverter.ToUInt16(memoryStream.GetBuffer(), Packet.KcpOpcodeIndex);
            Type   type    = OpcodeTypeComponent.Instance.GetType(opcode);
            object message = MessageSerializeHelper.DeserializeFrom(opcode, type, memoryStream);

            if (message is IResponse response)
            {
                session.OnRead(opcode, response);
                return;
            }

            OpcodeHelper.LogMsg(session.DomainZone(), opcode, message);

            DispatchAsync(session, opcode, message).Coroutine();
        }
Ejemplo n.º 3
0
        public static (ushort, MemoryStream) MessageToStream(object message, int count = 0)
        {
            MemoryStream stream = GetStream(Packet.OpcodeLength + count);

            ushort opcode = OpcodeTypeComponent.Instance.GetOpcode(message.GetType());

            stream.Seek(Packet.OpcodeLength, SeekOrigin.Begin);
            stream.SetLength(Packet.OpcodeLength);

            stream.GetBuffer().WriteTo(0, opcode);

            MessageSerializeHelper.SerializeTo(opcode, message, stream);

            stream.Seek(0, SeekOrigin.Begin);
            return(opcode, stream);
        }
Ejemplo n.º 4
0
        public static (ushort, MemoryStream) MessageToStream(object message)
        {
            int          headOffset = Packet.ActorIdLength;
            MemoryStream stream     = GetStream(headOffset + Packet.OpcodeLength);

            ushort opcode = OpcodeTypeComponent.Instance.GetOpcode(message.GetType());

            stream.Seek(headOffset + Packet.OpcodeLength, SeekOrigin.Begin);
            stream.SetLength(headOffset + Packet.OpcodeLength);

            stream.GetBuffer().WriteTo(headOffset, opcode);

            MessageSerializeHelper.SerializeTo(opcode, message, stream);

            stream.Seek(0, SeekOrigin.Begin);
            return(opcode, stream);
        }
Ejemplo n.º 5
0
        public static async ETTask <IActorResponse> Call(
            this ActorMessageSenderComponent self,
            long actorId,
            IActorRequest request,
            bool needException = true
            )
        {
            request.RpcId = self.GetRpcId();

            if (actorId == 0)
            {
                throw new Exception($"actor id is 0: {request}");
            }

            (ushort _, MemoryStream stream) = MessageSerializeHelper.MessageToStream(request);

            return(await self.Call(actorId, request.RpcId, stream, needException));
        }
Ejemplo n.º 6
0
        public static (ushort, MemoryStream) MessageToStream(long actorId, object message, int count = 0)
        {
            int          actorSize = sizeof(long);
            MemoryStream stream    = GetStream(actorSize + Packet.OpcodeLength + count);

            ushort opcode = OpcodeTypeComponent.Instance.GetOpcode(message.GetType());

            stream.Seek(actorSize + Packet.OpcodeLength, SeekOrigin.Begin);
            stream.SetLength(actorSize + Packet.OpcodeLength);

            // 写入actorId
            stream.GetBuffer().WriteTo(0, actorId);
            stream.GetBuffer().WriteTo(actorSize, opcode);

            MessageSerializeHelper.SerializeTo(opcode, message, stream);

            stream.Seek(0, SeekOrigin.Begin);
            return(opcode, stream);
        }
Ejemplo n.º 7
0
        public static async ETTask <IActorResponse> Call(this ActorLocationSenderComponent self, long entityId, IActorRequest iActorRequest)
        {
            ActorLocationSender actorLocationSender = self.GetOrCreate(entityId);

            // 先序列化好
            int rpcId = ActorMessageSenderComponent.Instance.GetRpcId();

            iActorRequest.RpcId             = rpcId;
            (ushort _, MemoryStream stream) = MessageSerializeHelper.MessageToStream(0, iActorRequest);

            long actorLocationSenderInstanceId = actorLocationSender.InstanceId;

            using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.ActorLocationSender, entityId))
            {
                if (actorLocationSender.InstanceId != actorLocationSenderInstanceId)
                {
                    throw new RpcException(ErrorCore.ERR_ActorTimeout, $"{stream.ToActorMessage()}");
                }

                // 队列中没处理的消息返回跟上个消息一样的报错
                if (actorLocationSender.Error == ErrorCore.ERR_NotFoundActor)
                {
                    return(ActorHelper.CreateResponse(iActorRequest, actorLocationSender.Error));
                }

                try
                {
                    return(await self.CallInner(actorLocationSender, rpcId, stream));
                }
                catch (RpcException)
                {
                    self.Remove(actorLocationSender.Id);
                    throw;
                }
                catch (Exception e)
                {
                    self.Remove(actorLocationSender.Id);
                    throw new Exception($"{stream.ToActorMessage()}", e);
                }
            }
        }
Ejemplo n.º 8
0
        public void Send(IMessage message)
        {
            switch (this.AService.ServiceType)
            {
            case ServiceType.Inner:
            {
                (ushort opcode, MemoryStream stream) = MessageSerializeHelper.MessageToStream(0, message);
                OpcodeHelper.LogMsg(this.DomainZone(), opcode, message);
                this.Send(0, stream);
                break;
            }

            case ServiceType.Outer:
            {
                (ushort opcode, MemoryStream stream) = MessageSerializeHelper.MessageToStream(message);
                OpcodeHelper.LogMsg(this.DomainZone(), opcode, message);
                this.Send(0, stream);
                break;
            }
            }
        }
Ejemplo n.º 9
0
        public void Dispatch(Session session, MemoryStream memoryStream)
        {
            ushort opcode  = BitConverter.ToUInt16(memoryStream.GetBuffer(), Packet.KcpOpcodeIndex);
            Type   type    = OpcodeTypeComponent.Instance.GetType(opcode);
            object message = MessageSerializeHelper.DeserializeFrom(opcode, type, memoryStream);

            if (TimeHelper.ClientFrameTime() - this.lastMessageTime > 3000)
            {
                Log.Info($"可能导致卡死的消息: {this.LastMessage}");
            }

            this.lastMessageTime = TimeHelper.ClientFrameTime();
            this.LastMessage     = message;

            if (message is IResponse response)
            {
                session.OnRead(opcode, response);
                return;
            }

            OpcodeHelper.LogMsg(session.DomainZone(), opcode, message);
            // 普通消息或者是Rpc请求消息
            MessageDispatcherComponent.Instance.Handle(session, opcode, message);
        }
Ejemplo n.º 10
0
 public void Send(long actorId, IMessage message)
 {
     (ushort opcode, MemoryStream stream) = MessageSerializeHelper.MessageToStream(actorId, message);
     OpcodeHelper.LogMsg(this.DomainZone(), opcode, message);
     this.Send(actorId, stream);
 }
Ejemplo n.º 11
0
        public void Dispatch(Session session, MemoryStream memoryStream)
        {
            ushort opcode = 0;

            try
            {
                long actorId = BitConverter.ToInt64(memoryStream.GetBuffer(), Packet.ActorIdIndex);
                opcode = BitConverter.ToUInt16(memoryStream.GetBuffer(), Packet.OpcodeIndex);
                Type   type    = null;
                object message = null;
#if SERVER
                // 内网收到外网消息,有可能是gateUnit消息,还有可能是gate广播消息
                if (OpcodeTypeComponent.Instance.IsOutrActorMessage(opcode))
                {
                    InstanceIdStruct instanceIdStruct = new InstanceIdStruct(actorId);
                    instanceIdStruct.Process = GlobalDefine.Options.Process;
                    long realActorId = instanceIdStruct.ToLong();


                    Entity entity = Game.EventSystem.Get(realActorId);
                    if (entity == null)
                    {
                        type    = OpcodeTypeComponent.Instance.GetType(opcode);
                        message = MessageSerializeHelper.DeserializeFrom(opcode, type, memoryStream);
                        Log.Error($"not found actor: {session.DomainScene().Name}  {opcode} {realActorId} {message}");
                        return;
                    }

                    if (entity is Session gateSession)
                    {
                        // 发送给客户端
                        memoryStream.Seek(Packet.OpcodeIndex, SeekOrigin.Begin);
                        gateSession.Send(0, memoryStream);
                        return;
                    }
                }
#endif


                type    = OpcodeTypeComponent.Instance.GetType(opcode);
                message = MessageSerializeHelper.DeserializeFrom(opcode, type, memoryStream);

                if (message is IResponse iResponse && !(message is IActorResponse))
                {
                    session.OnRead(opcode, iResponse);
                    return;
                }

                OpcodeHelper.LogMsg(session.DomainZone(), opcode, message);

                // 收到actor消息,放入actor队列
                switch (message)
                {
                case IActorRequest iActorRequest:
                {
                    InstanceIdStruct instanceIdStruct = new InstanceIdStruct(actorId);
                    int fromProcess = instanceIdStruct.Process;
                    instanceIdStruct.Process = GlobalDefine.Options.Process;
                    long realActorId = instanceIdStruct.ToLong();

                    void Reply(IActorResponse response)
                    {
                        Session replySession = NetInnerComponent.Instance.Get(fromProcess);

                        // 发回真实的actorId 做查问题使用
                        replySession.Send(realActorId, response);
                    }

                    InnerMessageDispatcherHelper.HandleIActorRequest(opcode, realActorId, iActorRequest, Reply);
                    return;
                }

                case IActorResponse iActorResponse:
                {
                    InstanceIdStruct instanceIdStruct = new InstanceIdStruct(actorId);
                    instanceIdStruct.Process = GlobalDefine.Options.Process;
                    long realActorId = instanceIdStruct.ToLong();
                    InnerMessageDispatcherHelper.HandleIActorResponse(opcode, realActorId, iActorResponse);
                    return;
                }

                case IActorMessage iactorMessage:
                {
                    InstanceIdStruct instanceIdStruct = new InstanceIdStruct(actorId);
                    instanceIdStruct.Process = GlobalDefine.Options.Process;
                    long realActorId = instanceIdStruct.ToLong();
                    InnerMessageDispatcherHelper.HandleIActorMessage(opcode, realActorId, iactorMessage);
                    return;
                }

                default:
                {
                    MessageDispatcherComponent.Instance.Handle(session, opcode, message);
                    break;
                }
                }
            }
            catch (Exception e)
            {
                Log.Error($"InnerMessageDispatcher error: {opcode}\n{e}");
            }
        }
Ejemplo n.º 12
0
        public bool Parse()
        {
            while (true)
            {
                switch (this.state)
                {
                case ParserState.PacketSize:
                {
                    if (this.service.ServiceType == ServiceType.Inner)
                    {
                        if (this.buffer.Length < InnerPacketSizeLength)
                        {
                            return(false);
                        }


                        cacheMemoryStream.Position = 0;
                        this.buffer.Read(cacheMemoryStream, InnerPacketSizeLength);
                        this.packetSize = this.cacheMemoryStream.ToInt32(0);
                        if (this.packetSize > ushort.MaxValue * 16 || this.packetSize < Packet.MinPacketSize)
                        {
                            throw new Exception($"recv packet size error, 可能是外网探测端口: {this.packetSize}");
                        }
                    }
                    else
                    {
                        if (this.buffer.Length < OuterPacketSizeLength)
                        {
                            return(false);
                        }

                        cacheMemoryStream.Position = 0;
                        this.buffer.Read(cacheMemoryStream, OuterPacketSizeLength);
                        this.packetSize = this.cacheMemoryStream.ToUInt16(0);
                        if (this.packetSize < Packet.MinPacketSize)
                        {
                            throw new Exception($"recv packet size error, 可能是外网探测端口: {this.packetSize}");
                        }
                    }

                    this.state = ParserState.PacketBody;
                    break;
                }

                case ParserState.PacketBody:
                {
                    if (this.buffer.Length < this.packetSize)
                    {
                        return(false);
                    }

                    MemoryStream memoryStream = MessageSerializeHelper.GetStream(this.packetSize);
                    this.buffer.Read(memoryStream, this.packetSize);
                    //memoryStream.SetLength(this.packetSize - Packet.MessageIndex);
                    this.MemoryStream = memoryStream;

                    if (this.service.ServiceType == ServiceType.Inner)
                    {
                        memoryStream.Seek(Packet.MessageIndex, SeekOrigin.Begin);
                    }
                    else
                    {
                        memoryStream.Seek(Packet.OpcodeLength, SeekOrigin.Begin);
                    }

                    this.state = ParserState.PacketSize;
                    return(true);
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Ejemplo n.º 13
0
 public static void Send(this Session self, long actorId, IMessage message)
 {
     (ushort opcode, MemoryStream stream) = MessageSerializeHelper.MessageToStream(message);
     OpcodeHelper.LogMsg(self.DomainZone(), opcode, message);
     self.Send(actorId, stream);
 }