예제 #1
0
        private async Task Connection_PacketReceived(object sender, PacketReceivedEventArgs args)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            Interlocked.Increment(ref _packetCount);

            if (typeof(RequestPacket).IsAssignableFrom(args.Packet.GetPacketType()))
            {
                if (!string.IsNullOrWhiteSpace(args.Packet.Destination))
                {
                    var sendCount = 0;

                    var connections = ConnectionProvider.GetConnections(args.Packet.Destination, true).ToArray();

                    Log.Info($"Sending {args.Packet} to {connections.Length} connections: {string.Join(",", connections.Take(10))}");

                    try {
                        foreach (var connection in connections)
                        {
                            try {
                                var response = await connection.Send(args.Packet);

                                if (args.Packet.Flags.HasFlag(PacketFlag.AckRequired))
                                {
                                    if (response == null)
                                    {
                                        throw new ErrorResponseException(ErrorResponseCodes.UnhandledRequest, $"Packet {args.Packet} routed to {args.Packet.Destination}, but they didn't handle the request.", false);
                                    }

                                    var responsePacket = (ResponsePacket)response;

                                    await args.Connection.Respond(args.PacketId, responsePacket);
                                }

                                sendCount++;
                            } catch (Exception ex) when(!(ex is ErrorResponseException))
                            {
                                Log.Warn(ex);
                            }
                        }

                        if (sendCount < 1)
                        {
                            Log.Warn($"Unable to deliver packet to user {args.Packet.Destination}, they are offline or the destination is invalid.");
                            throw new ErrorResponseException(ErrorResponseCodes.UserOffline, $"Unable to deliver packet to user {args.Packet.Destination}, they are offline of the destination is invalid.", false);
                        }
                    } catch (ErrorResponseException ex) {
                        var err = new ErrorResponseData(ex.Code, ex.Message, ex.IsCritical);
                        await args.Connection.Respond(args.PacketId, new ResponsePacket(err));
                    }

                    Log.Info($"Sent {args.Packet} to {sendCount} clients");

                    args.IsHandled = true;
                }
            }
        }
예제 #2
0
 public ErrorResponseException(ErrorResponseData data)
     : this(data.Code, data.Message, data.IsCritical)
 {
 }