private async Task ConnectUdpLoopAsync(ushort sessionId) { IPEndPoint localEp = _udpSocket.GetLocalEndPoint(); var writer = NetPool.DataWriterPool.Alloc(); try { writer.Write(_connectId); writer.Write(localEp); var packet = NetPool.PacketPool.Alloc(PacketProperty.RequestConnection, writer); try { packet.DeliveryMethod = DeliveryMethod.Unreliable; packet.SessionIdForConnection = sessionId; SocketError error = SocketError.Success; while (State == SessionState.Initialized && IsUdpConnected == false) { _udpSocket.SendTo(packet.RawData, 0, packet.Size, _serverUdpEndPoint, ref error); await Task.Delay(100); } } finally { NetPool.PacketPool.Free(packet); } } finally { NetPool.DataWriterPool.Free(writer); } }
private bool OnPreProcessUdpRawData(byte[] data, int size, NetPacket cachedPacket, IPEndPoint endPoint) { Interlocked.Increment(ref _statistic.UdpReceivedCount); Interlocked.Add(ref _statistic.UdpReceivedBytes, size); try { switch (cachedPacket.Property) { case PacketProperty.UserData: case PacketProperty.Ack: case PacketProperty.ViewRequest: { // P2p 데이터를 릴레이하자 try { ushort sessionId = cachedPacket.P2pSessionId; // 0이라면 서버와의 udp 통신 if (sessionId == 0) { return(false); } Interlocked.Increment(ref _statistic.RelayServCount); Interlocked.Add(ref _statistic.RelayServBytes, size); var targetSession = _sessionManager.FindSession(sessionId) as ServerSession; if (targetSession == null) { return(true); } var targetEp = targetSession.UdpChannel.PunchedEndPoint; if (targetEp == null) { return(true); } ISession senderSession; _udpSocket.TryGetSession(endPoint, out senderSession); if (senderSession == null) { return(true); } //_logger.LogInformation($"Relay to {sessionId} {targetSession.UdpChannel.PunchedEndPoint} from {senderSession.SessionId}"); // 보낸이를 수정해서 보내주자 cachedPacket.P2pSessionId = senderSession.SessionId; SocketError error = SocketError.Success; _udpSocket.SendTo(data, 0, size, targetEp, ref error); } catch { } } break; case PacketProperty.RequestConnection: { ushort sessionId = cachedPacket.SessionIdForConnection; NetDataReader reader = new NetDataReader(cachedPacket); long connectId = reader.ReadInt64(); IPEndPoint localEp = reader.ReadIPEndPoint(); var session = _sessionManager.FindSession(sessionId) as ServerSession; if (session != null && session.ConnectId == connectId) { session.UdpChannel.LocalEndPoint = localEp; session.UdpChannel.RemoteEndPoint = endPoint; if (session.UdpChannel.SetPunchedEndPoint(endPoint) == true) { _udpSocket.AddSession(session); //_logger.LogInformation($"Connect Udp {session.SessionId} {endPoint}"); } // 응답을 보내자 NetPacket sendPacket = NetPool.PacketPool.Alloc(PacketProperty.ResponseConnection); try { // 서버는 0번임 sendPacket.SessionIdForConnection = 0; sendPacket.DeliveryMethod = DeliveryMethod.Unreliable; SocketError error = SocketError.Success; _udpSocket.SendTo(sendPacket.RawData, 0, sendPacket.Size, endPoint, ref error); //_logger.LogInformation($"send ResponseConnection to {endPoint}"); } finally { NetPool.PacketPool.Free(sendPacket); } } } break; case PacketProperty.ResponseConnection: { } break; default: return(false); } } catch (Exception ex) { OnErrored?.Invoke(ex); return(true); } return(true); }