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