public static async Task HandleData(Campaign campaign, AckHandler ackHandler, NackHandler nackHandler)
        {
            if (VERBOSE)
            {
                Console.WriteLine($" [-] Campaign {campaign.Id} RECEIVED at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}.");
            }

            var indexingResult = await _campaignIndexer.IndexCampaignAsync(campaign);

            if (indexingResult.Notifications.Any())
            {
                if (VERBOSE)
                {
                    foreach (var notification in indexingResult.Notifications)
                    {
                        Console.WriteLine($" [-] {notification.Message} at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}.");
                    }
                }

                if (indexingResult.IsInvalid)
                {
                    nackHandler(requeue: false);
                    return;
                }
            }

            if (VERBOSE)
            {
                Console.WriteLine($" [x] Campaign {campaign.Id} DONE indexing at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}.");
            }

            ackHandler();
        }
        public static async Task HandleData(Visit visit, AckHandler ackHandler, NackHandler nackHandler)
        {
            if (VERBOSE)
            {
                Console.WriteLine($" [-] Vist {visit.Id} RECEIVED at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}.");
            }

            var pushingResult = await _campaignPusher.PushCampaignAsync(visit);

            if (pushingResult.Notifications.Any())
            {
                if (VERBOSE)
                {
                    foreach (var notification in pushingResult.Notifications)
                    {
                        Console.WriteLine($" [-] {notification.Message} at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}.");
                    }
                }

                if (pushingResult.IsInvalid)
                {
                    nackHandler(requeue: false);
                    return;
                }
            }

            if (VERBOSE)
            {
                Console.WriteLine($" [x] Visit {visit.Id} DONE pushing campaign at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}.");
            }

            ackHandler();
        }
Example #3
0
        public void UnregisteredAcksCantBeTriggered()
        {
            var ackHandler = new AckHandler(cancelAcksOnTimeout: false,
                                            ackThreshold: TimeSpan.Zero,
                                            ackInterval: TimeSpan.Zero);

            Assert.False(ackHandler.TriggerAck("foo"));
        }
Example #4
0
        public async Task AcksLastingLongerThanThresholdAreCompleted()
        {
            var ackHandler = new AckHandler(completeAcksOnTimeout: true,
                                            ackThreshold: TimeSpan.FromSeconds(1),
                                            ackInterval: TimeSpan.FromSeconds(1));

            await Assert.ThrowsAsync <TaskCanceledException>(() => ackHandler.CreateAck("foo").OrTimeout());
        }
Example #5
0
        public void UnregisteredAcksCantBeTriggered()
        {
            var ackHandler = new AckHandler(completeAcksOnTimeout: false,
                                            ackThreshold: TimeSpan.Zero,
                                            ackInterval: TimeSpan.Zero);

            Assert.False(ackHandler.TriggerAck("foo"));
        }
        public void cant_ack_without_message_id()
        {
            var frame  = new BasicFrame("ACK");
            var client = Substitute.For <IStompClient>();

            var    sut    = new AckHandler();
            Action actual = () => sut.Process(client, frame);

            actual.ShouldThrow <BadRequestException>();
        }
Example #7
0
        public P2PAckMessageEventArgs(P2PMessage p2pMessage, AckHandler ackHandler, int timeoutSec)
            : base(p2pMessage)
        {
            this.ackHandler = ackHandler;
            this.deleteTick = timeoutSec;

            if (timeoutSec != 0)
            {
                AddSeconds(timeoutSec);
            }
        }
Example #8
0
        public P2PAckMessageEventArgs(P2PMessage p2pMessage, AckHandler ackHandler, int timeoutSec)
            : base(p2pMessage)
        {
            this.ackHandler = ackHandler;
            this.deleteTick = timeoutSec;

            if (timeoutSec != 0)
            {
                AddSeconds(timeoutSec);
            }
        }
Example #9
0
        public void TriggeredAcksAreCompleted()
        {
            var ackHandler = new AckHandler(cancelAcksOnTimeout: false,
                                            ackThreshold: TimeSpan.Zero,
                                            ackInterval: TimeSpan.Zero);

            Task task = ackHandler.CreateAck("foo");

            Assert.True(ackHandler.TriggerAck("foo"));
            Assert.True(task.IsCompleted);
        }
Example #10
0
        public void TriggeredAcksAreCompleted()
        {
            var ackHandler = new AckHandler(completeAcksOnTimeout: false,
                                            ackThreshold: TimeSpan.Zero,
                                            ackInterval: TimeSpan.Zero);

            Task task = ackHandler.CreateAck("foo");

            Assert.True(ackHandler.TriggerAck("foo"));
            Assert.True(task.IsCompleted);
        }
Example #11
0
        public void Send(P2PMessage p2pMessage, int ackTimeout, AckHandler ackHandler)
        {
            ResetTimeoutTimer();

            if (p2pBridge == null)
            {
                MigrateToOptimalBridge();
            }

            p2pBridge.Send(this, Remote, RemoteContactEndPointID, p2pMessage, ackTimeout, ackHandler);
        }
        public RedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger,
                                       IOptions <RedisOptions> options,
                                       IHubProtocolResolver hubProtocolResolver)
        {
            _logger     = logger;
            _options    = options.Value;
            _ackHandler = new AckHandler();
            _channels   = new RedisChannels(typeof(THub).FullName);
            _protocol   = new RedisProtocol(hubProtocolResolver.AllProtocols);

            RedisLog.ConnectingToEndpoints(_logger, options.Value.Options.EndPoints, _serverName);
        }
        public RedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger,
                                       IOptions <RedisOptions> options,
                                       IHubProtocolResolver hubProtocolResolver)
        {
            _logger     = logger;
            _options    = options.Value;
            _ackHandler = new AckHandler();
            _channels   = new RedisChannels(typeof(THub).FullName);
            _protocol   = new RedisProtocol(hubProtocolResolver.AllProtocols);

            var writer = new LoggerTextWriter(logger);

            RedisLog.ConnectingToEndpoints(_logger, options.Value.Options.EndPoints, _serverName);
            _redisServerConnection = _options.Connect(writer);

            _redisServerConnection.ConnectionRestored += (_, e) =>
            {
                // We use the subscription connection type
                // Ignore messages from the interactive connection (avoids duplicates)
                if (e.ConnectionType == ConnectionType.Interactive)
                {
                    return;
                }

                RedisLog.ConnectionRestored(_logger);
            };

            _redisServerConnection.ConnectionFailed += (_, e) =>
            {
                // We use the subscription connection type
                // Ignore messages from the interactive connection (avoids duplicates)
                if (e.ConnectionType == ConnectionType.Interactive)
                {
                    return;
                }

                RedisLog.ConnectionFailed(_logger, e.Exception);
            };

            if (_redisServerConnection.IsConnected)
            {
                RedisLog.Connected(_logger);
            }
            else
            {
                RedisLog.NotConnected(_logger);
            }
            _bus = _redisServerConnection.GetSubscriber();

            SubscribeToAll();
            SubscribeToGroupManagementChannel();
            SubscribeToAckChannel();
        }
Example #14
0
        public void AcksLastingLongerThanThresholdAreCancelled()
        {
            var ackHandler = new AckHandler(cancelAcksOnTimeout: true,
                                            ackThreshold: TimeSpan.FromSeconds(1),
                                            ackInterval: TimeSpan.FromSeconds(1));

            Task task = ackHandler.CreateAck("foo");

            Thread.Sleep(TimeSpan.FromSeconds(5));

            Assert.True(task.IsCanceled);
        }
        public ShardingRedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger,
                                               IOptions <ShardingRedisOptions> options,
                                               IHubProtocolResolver hubProtocolResolver)
        {
            _logger     = logger;
            _options    = options.Value;
            _ackHandler = new AckHandler();
            _channels   = new RedisChannels(typeof(THub).FullName);
            _protocol   = new RedisProtocol(hubProtocolResolver.AllProtocols);

            _ = EnsureRedisServerConnection();
        }
Example #16
0
        public void AcksLastingLongerThanThresholdAreCancelled()
        {
            var ackHandler = new AckHandler(cancelAcksOnTimeout: true,
                                            ackThreshold: TimeSpan.FromSeconds(1),
                                            ackInterval: TimeSpan.FromSeconds(1));

            Task task = ackHandler.CreateAck("foo");

            Thread.Sleep(TimeSpan.FromSeconds(5));

            Assert.True(task.IsCanceled);
        }
        public RedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger,
                                       IOptions <RedisOptions> options)
        {
            _logger     = logger;
            _options    = options.Value;
            _ackHandler = new AckHandler();

            var writer = new LoggerTextWriter(logger);

            _logger.ConnectingToEndpoints(options.Value.Options.EndPoints);
            _redisServerConnection = _options.Connect(writer);

            _redisServerConnection.ConnectionRestored += (_, e) =>
            {
                // We use the subscription connection type
                // Ignore messages from the interactive connection (avoids duplicates)
                if (e.ConnectionType == ConnectionType.Interactive)
                {
                    return;
                }

                _logger.ConnectionRestored();
            };

            _redisServerConnection.ConnectionFailed += (_, e) =>
            {
                // We use the subscription connection type
                // Ignore messages from the interactive connection (avoids duplicates)
                if (e.ConnectionType == ConnectionType.Interactive)
                {
                    return;
                }

                _logger.ConnectionFailed(e.Exception);
            };

            if (_redisServerConnection.IsConnected)
            {
                _logger.Connected();
            }
            else
            {
                _logger.NotConnected();
            }
            _bus = _redisServerConnection.GetSubscriber();

            SubscribeToHub();
            SubscribeToAllExcept();
            SubscribeToInternalGroup();
            SubscribeToInternalServerName();
        }
        public void cant_ack_if_message_Was_not_found()
        {
            var frame = new BasicFrame("ACK");

            frame.Headers["id"] = "aa";
            var client = Substitute.For <IStompClient>();

            client.IsFramePending("aa").Returns(false);

            var    sut    = new AckHandler();
            Action actual = () => sut.Process(client, frame);

            actual.ShouldThrow <BadRequestException>();
        }
Example #19
0
        /// <summary>
        /// Sends a message with the specified <see cref="P2PMessage"/> and <see cref="AckHandler"/>.
        /// </summary>
        public virtual void SendMessage(P2PMessage p2pMessage, int ackTimeout, AckHandler ackHandler)
        {
            Debug.Assert(p2pMessage.Version == version);

            p2pMessage.Header.SessionId = p2pSession.SessionId;

            // If not an ack, set the footer (p2pv1 only)
            if (p2pMessage.Version == P2PVersion.P2PV1 && (p2pMessage.V1Header.Flags & P2PFlag.Acknowledgement) != P2PFlag.Acknowledgement)
            {
                p2pMessage.Footer = ApplicationId;
            }

            p2pSession.Send(p2pMessage, ackTimeout, ackHandler);
        }
        public MsmqHubLifetimeManager(
            ILogger <MsmqHubLifetimeManager <THub> > logger,
            IOptions <MsmqOptions> options,
            IHubProtocolResolver hubProtocolResolver,
            IMsmqBus msmqBus)
        {
            this.logger     = logger;
            this.options    = options.Value;
            this.protocol   = new MsmqProtocol(hubProtocolResolver.AllProtocols);
            this.msmqBus    = msmqBus;
            this.queues     = new MsmqQueues(this.options.ApplicationName);
            this.ackHandler = new AckHandler();

            MsmqLog.ConnectingToEndpoints(this.logger, this.options.ConnectionString, this.options.ApplicationName);
            _ = this.EnsureMsmqServerConnection();
        }
        public void ack()
        {
            var frame = new BasicFrame("ACK");

            frame.Headers["id"] = "aa";
            var client       = Substitute.For <IStompClient>();
            var subscription = Substitute.For <Subscription>(client, "aa");

            client.IsFramePending("aa").Returns(true);
            client.GetSubscription("aa").Returns(subscription);

            var sut = new AckHandler();

            sut.Process(client, frame);

            subscription.Received().Ack("aa");
        }
        public void enqueue_if_transaction_was_specified()
        {
            var frame = new BasicFrame("ACK");

            frame.Headers["id"]          = "aa";
            frame.Headers["transaction"] = "sdfsd";
            var client       = Substitute.For <IStompClient>();
            var subscription = Substitute.For <Subscription>(client, "aa");

            client.IsFramePending("aa").Returns(true);
            client.GetSubscription("aa").Returns(subscription);

            var sut = new AckHandler();

            sut.Process(client, frame);

            client.Received().EnqueueInTransaction("sdfsd", Arg.Any <Action>(), Arg.Any <Action>());
            subscription.DidNotReceive().Ack("aa");
        }
Example #23
0
        /// <summary>
        /// Constructs the <see cref="RedisHubLifetimeManager{THub}"/> with types from Dependency Injection.
        /// </summary>
        /// <param name="logger">The logger to write information about what the class is doing.</param>
        /// <param name="options">The <see cref="RedisOptions"/> that influence behavior of the Redis connection.</param>
        /// <param name="hubProtocolResolver">The <see cref="IHubProtocolResolver"/> to get an <see cref="IHubProtocol"/> instance when writing to connections.</param>
        /// <param name="globalHubOptions">The global <see cref="HubOptions"/>.</param>
        /// <param name="hubOptions">The <typeparamref name="THub"/> specific options.</param>
        public RedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger,
                                       IOptions <RedisOptions> options,
                                       IHubProtocolResolver hubProtocolResolver,
                                       IOptions <HubOptions>?globalHubOptions,
                                       IOptions <HubOptions <THub> >?hubOptions)
        {
            _logger     = logger;
            _options    = options.Value;
            _ackHandler = new AckHandler();
            _channels   = new RedisChannels(typeof(THub).FullName !);
            if (globalHubOptions != null && hubOptions != null)
            {
                _protocol = new RedisProtocol(new DefaultHubMessageSerializer(hubProtocolResolver, globalHubOptions.Value.SupportedProtocols, hubOptions.Value.SupportedProtocols));
            }
            else
            {
                var supportedProtocols = hubProtocolResolver.AllProtocols.Select(p => p.Name).ToList();
                _protocol = new RedisProtocol(new DefaultHubMessageSerializer(hubProtocolResolver, supportedProtocols, null));
            }

            RedisLog.ConnectingToEndpoints(_logger, options.Value.Configuration.EndPoints, _serverName);
            _ = EnsureRedisServerConnection();
        }
Example #24
0
        /// <summary>
        /// Send a P2P Message to the specified P2PSession.
        /// </summary>
        /// <param name="session">
        /// The application layer, which is a <see cref="P2PSession"/>
        /// </param>
        /// <param name="remote">
        /// he receiver <see cref="Contact"/>
        /// </param>
        /// <param name="remoteGuid">
        /// A <see cref="Guid"/>
        /// </param>
        /// <param name="msg">
        /// he <see cref="P2PMessage"/> to be sent.
        /// </param>
        /// <param name="ackTimeout">
        /// The maximum time to wait for an ACK. <see cref="System.Int32"/>
        /// </param>
        /// <param name="ackHandler">
        /// The <see cref="AckHandler"/> to handle the ACK.
        /// </param>
        public virtual void Send(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg, int ackTimeout, AckHandler ackHandler)
        {
            if (remote == null)
            {
                throw new ArgumentNullException("remote");
            }

            P2PMessage[] msgs = SetSequenceNumberAndRegisterAck(session, remote, msg, ackHandler, ackTimeout);

            if (session == null)
            {
                if (!IsOpen)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                      "Send called with no session on a closed bridge", GetType().Name);

                    return;
                }

                // Bypass queueing
                foreach (P2PMessage m in msgs)
                {
                    SendOnePacket(null, remote, remoteGuid, m);
                }

                return;
            }

            if (!SuitableFor(session))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                  "Send called with a session this bridge is not suitable for", GetType().Name);
                return;
            }

            lock (sendQueues)
            {
                if (!sendQueues.ContainsKey(session))
                {
                    sendQueues[session] = new P2PSendQueue();
                }
            }
            lock (sendQueues[session])
            {
                foreach (P2PMessage m in msgs)
                {
                    sendQueues[session].Enqueue(remote, remoteGuid, m);
                }
            }

            ProcessSendQueues();
        }
Example #25
0
 public void Send(P2PMessage p2pMessage, AckHandler ackHandler)
 {
     Send(p2pMessage, P2PBridge.DefaultTimeout, ackHandler);
 }
 public TestServiceConnectionContainer(List <IServiceConnection> serviceConnections, HubServiceEndpoint endpoint = null, AckHandler ackHandler = null, IServiceConnectionFactory factory = null, ILogger logger = null)
     : base(factory, 0, endpoint, serviceConnections, ackHandler: ackHandler, logger: logger ?? NullLogger.Instance)
 {
 }
Example #27
0
        private void SendChunk()
        {
            if (!_sendingData)
            {
                return;
            }

            P2PDataMessage p2pChunk = new P2PDataMessage(P2PVersion);

            long offset = _dataStream.Position;

            // First chunk
            if (offset == 0)
            {
                if (P2PVersion == P2PVersion.P2PV1)
                {
                    P2PSession.IncreaseLocalIdentifier();

                    p2pChunk.V1Header.TotalSize = (ulong)_dataStream.Length;
                }
                else if (P2PVersion == P2PVersion.P2PV2)
                {
                    p2pChunk.V2Header.TFCombination = TFCombination.First;
                }
            }

            p2pChunk.Header.Identifier = P2PSession.LocalIdentifier;

            p2pChunk.WriteBytes(_dataStream, P2PSession.Bridge.MaxDataSize);

            AckHandler ackHandler = null;
            int        ackTimeout = P2PBridge.MaxTimeout;

            if (P2PVersion == P2PVersion.P2PV1)
            {
                p2pChunk.V1Header.Flags = P2PFlag.FileData;
            }
            else if (P2PVersion == P2PVersion.P2PV2)
            {
                p2pChunk.V2Header.PackageNumber  = packNum;
                p2pChunk.V2Header.TFCombination |= TFCombination.FileTransfer;

                if (p2pv2NextRAK < DateTime.Now)
                {
                    _sendingData = false; // Activate when ack received.

                    p2pChunk.V2Header.OperationCode |= (byte)OperationCode.RAK;
                    p2pv2NextRAK = DateTime.Now.AddSeconds(8);

                    ackTimeout = P2PBridge.DefaultTimeout;
                    ackHandler = delegate(P2PMessage ack)
                    {
                        _sendingData = true; // Ack received, continue sending...
                        SendChunk();
                    };
                }
            }

            if (_dataStream.Position == _dataStream.Length)
            {
                _sendingData = false;
                SendMessage(p2pChunk);

                // This is the last chunk of data, register the ACKHandler
                P2PMessage rak = new P2PMessage(P2PVersion);
                SendMessage(rak, P2PBridge.DefaultTimeout, delegate(P2PMessage ack)
                {
                    Abort();
                    OnTransferFinished(EventArgs.Empty);
                });
            }
            else
            {
                SendMessage(p2pChunk, ackTimeout, ackHandler);
            }

            OnProgressed(EventArgs.Empty);
        }
Example #28
0
 public void Send(P2PMessage p2pMessage, AckHandler ackHandler)
 {
     Send(p2pMessage, P2PBridge.DefaultTimeout, ackHandler);
 }
Example #29
0
        private P2PMessage[] SetSequenceNumberAndRegisterAck(P2PSession session, Contact remote, P2PMessage p2pMessage, AckHandler ackHandler, int timeout)
        {
            if (p2pMessage.Header.Identifier == 0)
            {
                if (p2pMessage.Version == P2PVersion.P2PV1)
                {
                    p2pMessage.Header.Identifier = ++sequenceId;
                }
                else if (p2pMessage.Version == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.Identifier = sequenceId;
                }
            }

            if (p2pMessage.Version == P2PVersion.P2PV1 && p2pMessage.V1Header.AckSessionId == 0)
            {
                p2pMessage.V1Header.AckSessionId = (uint)new Random().Next(50000, int.MaxValue);
            }
            if (p2pMessage.Version == P2PVersion.P2PV2 && p2pMessage.V2Header.PackageNumber == 0)
            {
                p2pMessage.V2Header.PackageNumber = packageNo;
            }

            P2PMessage[] msgs = p2pMessage.SplitMessage(MaxDataSize);

            if (p2pMessage.Version == P2PVersion.P2PV2)
            {
                // Correct local sequence no
                P2PMessage lastMsg = msgs[msgs.Length - 1];
                SequenceId = lastMsg.V2Header.Identifier + lastMsg.V2Header.MessageSize;
            }

            if (ackHandler != null)
            {
                P2PMessage firstMessage = msgs[0];
                RegisterAckHandler(new P2PAckMessageEventArgs(firstMessage, ackHandler, timeout));
            }

            if (session != null)
            {
                session.LocalIdentifier = SequenceId;
            }

            return msgs;
        }
        public RedisHubLifetimeManager(ILogger <RedisHubLifetimeManager <THub> > logger,
                                       IOptions <RedisOptions> options)
        {
            _logger     = logger;
            _options    = options.Value;
            _ackHandler = new AckHandler();

            var writer = new LoggerTextWriter(logger);

            _logger.LogInformation("Connecting to redis endpoints: {endpoints}", string.Join(", ", options.Value.Options.EndPoints.Select(e => EndPointCollection.ToString(e))));
            _redisServerConnection = _options.Connect(writer);
            if (_redisServerConnection.IsConnected)
            {
                _logger.LogInformation("Connected to redis");
            }
            else
            {
                // TODO: We could support reconnecting, like old SignalR does.
                throw new InvalidOperationException("Connection to redis failed.");
            }
            _bus = _redisServerConnection.GetSubscriber();

            var previousBroadcastTask = Task.CompletedTask;

            var channelName = _channelNamePrefix;

            _logger.LogInformation("Subscribing to channel: {channel}", channelName);
            _bus.Subscribe(channelName, async(c, data) =>
            {
                await previousBroadcastTask;

                _logger.LogTrace("Received message from redis channel {channel}", channelName);

                var message = DeserializeMessage <HubMessage>(data);

                // TODO: This isn't going to work when we allow JsonSerializer customization or add Protobuf
                var tasks = new List <Task>(_connections.Count);

                foreach (var connection in _connections)
                {
                    tasks.Add(WriteAsync(connection, message));
                }

                previousBroadcastTask = Task.WhenAll(tasks);
            });

            var allExceptTask = Task.CompletedTask;

            channelName = _channelNamePrefix + ".AllExcept";
            _logger.LogInformation("Subscribing to channel: {channel}", channelName);
            _bus.Subscribe(channelName, async(c, data) =>
            {
                await allExceptTask;

                _logger.LogTrace("Received message from redis channel {channel}", channelName);

                var message     = DeserializeMessage <RedisExcludeClientsMessage>(data);
                var excludedIds = message.ExcludedIds;

                // TODO: This isn't going to work when we allow JsonSerializer customization or add Protobuf

                var tasks = new List <Task>(_connections.Count);

                foreach (var connection in _connections)
                {
                    if (!excludedIds.Contains(connection.ConnectionId))
                    {
                        tasks.Add(WriteAsync(connection, message));
                    }
                }

                allExceptTask = Task.WhenAll(tasks);
            });

            channelName = _channelNamePrefix + ".internal.group";
            _bus.Subscribe(channelName, async(c, data) =>
            {
                var groupMessage = DeserializeMessage <GroupMessage>(data);

                if (groupMessage.Action == GroupAction.Remove)
                {
                    if (!await RemoveGroupAsyncCore(groupMessage.ConnectionId, groupMessage.Group))
                    {
                        // user not on this server
                        return;
                    }
                }

                if (groupMessage.Action == GroupAction.Add)
                {
                    if (!await AddGroupAsyncCore(groupMessage.ConnectionId, groupMessage.Group))
                    {
                        // user not on this server
                        return;
                    }
                }

                // Sending ack to server that sent the original add/remove
                await PublishAsync($"{_channelNamePrefix}.internal.{groupMessage.Server}", new GroupMessage
                {
                    Action       = GroupAction.Ack,
                    ConnectionId = groupMessage.ConnectionId,
                    Group        = groupMessage.Group,
                    Id           = groupMessage.Id
                });
            });

            // Create server specific channel in order to send an ack to a single server
            var serverChannel = $"{_channelNamePrefix}.internal.{_serverName}";

            _bus.Subscribe(serverChannel, (c, data) =>
            {
                var groupMessage = DeserializeMessage <GroupMessage>(data);

                if (groupMessage.Action == GroupAction.Ack)
                {
                    _ackHandler.TriggerAck(groupMessage.Id);
                }
            });
        }
Example #31
0
 public PulledMessage(BaseMessage message, AckHandler handler)
     : base(message)
 {
     _handler    = handler ?? throw new ArgumentNullException(nameof(handler));
     _pulledTime = DateTime.Now.ToTime();
 }
Example #32
0
 public TestBaseServiceConnectionContainer(List <IServiceConnection> serviceConnections, HubServiceEndpoint endpoint = null, AckHandler ackHandler = null)
     : base(null, 0, endpoint, serviceConnections, ackHandler: ackHandler)
 {
 }
Example #33
0
        public void Send(P2PMessage p2pMessage, int ackTimeout, AckHandler ackHandler)
        {
            ResetTimeoutTimer();

            if (p2pBridge == null)
                MigrateToOptimalBridge();

            p2pBridge.Send(this, Remote, RemoteContactEndPointID, p2pMessage, ackTimeout, ackHandler);
        }
Example #34
0
        /// <summary>
        /// Send a P2P Message to the specified P2PSession. 
        /// </summary>
        /// <param name="session">
        /// The application layer, which is a <see cref="P2PSession"/>
        /// </param>
        /// <param name="remote">
        /// he receiver <see cref="Contact"/>
        /// </param>
        /// <param name="remoteGuid">
        /// A <see cref="Guid"/>
        /// </param>
        /// <param name="msg">
        /// he <see cref="P2PMessage"/> to be sent.
        /// </param>
        /// <param name="ackTimeout">
        /// The maximum time to wait for an ACK. <see cref="System.Int32"/>
        /// </param>
        /// <param name="ackHandler">
        /// The <see cref="AckHandler"/> to handle the ACK.
        /// </param>      
        public virtual void Send(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg, int ackTimeout, AckHandler ackHandler)
        {
            if (remote == null)
                throw new ArgumentNullException("remote");

            P2PMessage[] msgs = SetSequenceNumberAndRegisterAck(session, remote, msg, ackHandler, ackTimeout);

            if (session == null)
            {
                if (!IsOpen)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                        "Send called with no session on a closed bridge", GetType().Name);

                    return;
                }

                // Bypass queueing
                foreach (P2PMessage m in msgs)
                {
                    SendOnePacket(null, remote, remoteGuid, m);
                }

                return;
            }

            if (!SuitableFor(session))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                        "Send called with a session this bridge is not suitable for", GetType().Name);
                return;
            }

            lock (sendQueues)
            {
                if (!sendQueues.ContainsKey(session))
                    sendQueues[session] = new P2PSendQueue();
            }
            lock (sendQueues[session])
            {
                foreach (P2PMessage m in msgs)
                    sendQueues[session].Enqueue(remote, remoteGuid, m);
            }

            ProcessSendQueues();
        }
Example #35
0
        /// <summary>
        /// Sends a message with the specified <see cref="P2PMessage"/> and <see cref="AckHandler"/>.
        /// </summary>
        public virtual void SendMessage(P2PMessage p2pMessage, int ackTimeout, AckHandler ackHandler)
        {
            Debug.Assert(p2pMessage.Version == version);

            p2pMessage.Header.SessionId = p2pSession.SessionId;

            // If not an ack, set the footer (p2pv1 only)
            if (p2pMessage.Version == P2PVersion.P2PV1 && (p2pMessage.V1Header.Flags & P2PFlag.Acknowledgement) != P2PFlag.Acknowledgement)
                p2pMessage.Footer = ApplicationId;

            p2pSession.Send(p2pMessage, ackTimeout, ackHandler);
        }
 private CustomizedPingTimerFactory(IServiceConnectionFactory serviceConnectionFactory, int minConnectionCount, HubServiceEndpoint endpoint, IReadOnlyList <IServiceConnection> initialConnections = null, ILogger logger = null, AckHandler ackHandler = null) : base(serviceConnectionFactory, minConnectionCount, endpoint, initialConnections, logger, ackHandler)
 {
 }
Example #37
0
 /// <summary>
 /// Emits an event on the socket which gets sent to the server and listens to an acknowledgement from the server
 /// </summary>
 /// <param name="ev">The name of the event</param>
 /// <param name="ackHandler">The delegate to be executed upon acknowledgement</param>
 /// <param name="data">The data to be serialized/sent</param>
 public void Emit(string ev, Action <JArray> ackHandler, params object[] data)
 {
     socketConnection.Send(Packet.Event(ev, data, nextEventID));
     ackHandlers[nextEventID] = new AckHandler(ackHandler);
     nextEventID++;
 }
Example #38
0
        private P2PMessage[] SetSequenceNumberAndRegisterAck(P2PSession session, Contact remote, P2PMessage p2pMessage, AckHandler ackHandler, int timeout)
        {
            if (p2pMessage.Header.Identifier == 0)
            {
                if (p2pMessage.Version == P2PVersion.P2PV1)
                {
                    p2pMessage.Header.Identifier = ++sequenceId;
                }
                else if (p2pMessage.Version == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.Identifier = sequenceId;
                }
            }

            if (p2pMessage.Version == P2PVersion.P2PV1 && p2pMessage.V1Header.AckSessionId == 0)
            {
                p2pMessage.V1Header.AckSessionId = (uint)new Random().Next(50000, int.MaxValue);
            }
            if (p2pMessage.Version == P2PVersion.P2PV2 && p2pMessage.V2Header.PackageNumber == 0)
            {
                p2pMessage.V2Header.PackageNumber = packageNo;
            }

            P2PMessage[] msgs = p2pMessage.SplitMessage(MaxDataSize);

            if (p2pMessage.Version == P2PVersion.P2PV2)
            {
                // Correct local sequence no
                P2PMessage lastMsg = msgs[msgs.Length - 1];
                SequenceId = lastMsg.V2Header.Identifier + lastMsg.V2Header.MessageSize;
            }

            if (ackHandler != null)
            {
                P2PMessage firstMessage = msgs[0];
                RegisterAckHandler(new P2PAckMessageEventArgs(firstMessage, ackHandler, timeout));
            }

            if (session != null)
            {
                session.LocalIdentifier = SequenceId;
            }

            return(msgs);
        }