示例#1
0
        public async Task BindToGlobalEventAsync()
        {
            #region Code snippet

            // Create client
            Pusher pusher = new Pusher(Config.AppKey, new PusherOptions
            {
                Authorizer = new FakeAuthoriser(),
                Cluster    = Config.Cluster,
            });
            pusher.Error += ErrorHandler;

            // Global event listener
            void GlobalListener(string eventName, PusherEvent eventData)
            {
                if (eventName == "client-chat-event")
                {
                    ChatMessage data = JsonConvert.DeserializeObject <ChatMessage>(eventData.Data);
                    Trace.TraceInformation($"Message from '{data.Name}': {data.Message}");
                }
            }

            // Bind global event listener
            pusher.BindAll(GlobalListener);

            // Unbind global event listener
            pusher.Unbind(GlobalListener);

            // Unbind all event listeners associated with the Pusher client
            pusher.UnbindAll();

            #endregion Code snippet

            await pusher.DisconnectAsync().ConfigureAwait(false);
        }
示例#2
0
        protected override async Task Run()
        {
            _pusher.ConnectionStateChanged += (_, state) =>
            {
                _logger.Information("Pusher connection state changed: {PusherConnectionState}", state);
            };

            _pusher.Subscribed += (_, channel) =>
            {
                _logger.Information("Pusher subscribed to channel: {PusherChannelName}", channel.Name);
            };

            await _pusher.ConnectAsync();

            await Task.WhenAll(
                _pusher.SubscribeAsync("sim-data"),
                _pusher.SubscribeAsync("temporal"),
                _pusher.SubscribeAsync("ticker")
                );

            _pusher.BindAll(GlobalHandler);
            _pusher.Bind("sim-data", WrapHandler(SimDataHandler));
            _pusher.Bind("temporal-message", WrapHandler(TemporalHandler));
            _pusher.Bind("ticker-message", WrapHandler(TickerHandler));
            _pusher.Bind("game-data", WrapHandler(GameDataHandler));

            // Wait forever
            await SubscribeLoop();
        }
        public async Task PusherEventEmitterPrivateEncryptedChannelTestAsync()
        {
            // Arrange
            byte[] encryptionKey = GenerateEncryptionMasterKey();
            var    pusherServer  = new PusherServer.Pusher(Config.AppId, Config.AppKey, Config.AppSecret, new PusherServer.PusherOptions
            {
                Cluster             = Config.Cluster,
                EncryptionMasterKey = encryptionKey,
            });

            ChannelTypes   channelType          = ChannelTypes.PrivateEncrypted;
            Pusher         localPusher          = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients, encryptionKey: encryptionKey);
            string         testEventName        = "private-encrypted-event-test";
            AutoResetEvent globalEventReceived  = new AutoResetEvent(false);
            AutoResetEvent channelEventReceived = new AutoResetEvent(false);
            PusherEvent    globalEvent          = null;
            PusherEvent    channelEvent         = null;
            PusherEvent    pusherEvent          = CreatePusherEvent(channelType, testEventName);

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(pusherEvent.ChannelName).ConfigureAwait(false);

            void GeneralListener(string eventName, PusherEvent eventData)
            {
                if (eventName == testEventName)
                {
                    globalEvent = eventData;
                    globalEventReceived.Set();
                }
            }

            void Listener(PusherEvent eventData)
            {
                channelEvent = eventData;
                channelEventReceived.Set();
            }

            EventTestData data = new EventTestData
            {
                TextField    = ExpectedTextField,
                IntegerField = ExpectedIntegerField,
            };

            // Act
            localPusher.BindAll(GeneralListener);
            localChannel.Bind(testEventName, Listener);
            await pusherServer.TriggerAsync(pusherEvent.ChannelName, testEventName, data).ConfigureAwait(false);

            // Assert
            Assert.IsTrue(globalEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            Assert.IsTrue(channelEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            AssertPusherEventsAreEqual(channelType, pusherEvent, globalEvent);
            AssertPusherEventsAreEqual(channelType, pusherEvent, channelEvent);
        }
        private async Task DynamicEventEmitterTestAsync(ChannelTypes channelType)
        {
            // Arrange
            Pusher         localPusher          = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients);
            string         testEventName        = "client-dynamic-event-test";
            AutoResetEvent globalEventReceived  = new AutoResetEvent(false);
            AutoResetEvent channelEventReceived = new AutoResetEvent(false);
            dynamic        globalEvent          = null;
            dynamic        channelEvent         = null;
            dynamic        dynamicEventData     = CreateDynamicEventData();
            string         channelName          = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel remoteChannel = await _remoteClient.SubscribeAsync(channelName).ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(channelName).ConfigureAwait(false);

            void GeneralListener(string eventName, dynamic eventData)
            {
                if (eventName == testEventName)
                {
                    globalEvent = eventData;
                    globalEventReceived.Set();
                }
            }

            void Listener(dynamic eventData)
            {
                channelEvent = eventData;
                channelEventReceived.Set();
            }

            // Act
            localPusher.BindAll(GeneralListener);
            localChannel.Bind(testEventName, Listener);
            remoteChannel.Trigger(testEventName, dynamicEventData);

            // Assert
            Assert.IsTrue(globalEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            Assert.IsTrue(channelEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            ValidateDynamicEvent(channelName, testEventName, globalEvent);
            ValidateDynamicEvent(channelName, testEventName, channelEvent);
        }
示例#5
0
        // Pusher Initiation / Connection
        private static async Task InitPusher()
        {
            _pusher = new Pusher(Config.AppKey, new PusherOptions
            {
                Authorizer  = new HttpAuthorizer("http://localhost:8888/auth/" + HttpUtility.UrlEncode(_name)),
                Cluster     = Config.Cluster,
                Encrypted   = Config.Encrypted,
                TraceLogger = new TraceLogger(),
            });
            _pusher.ConnectionStateChanged += PusherConnectionStateChanged;
            _pusher.Error += PusherError;

            // Setup private channel
            string privateChannelName = "private-channel";

            _pusher.Subscribed += (sender, channel) =>
            {
                if (channel.Name == privateChannelName)
                {
                    string message = $"{Environment.NewLine}Hi {_name}! Type 'quit' to exit, otherwise type anything to chat!{Environment.NewLine}";
                    Console.WriteLine(message);
                }
            };

            // Setup presence channel
            string presenceChannelName = "presence-channel";

            _pusher.Subscribed += (sender, channel) =>
            {
                if (channel.Name == presenceChannelName)
                {
                    ListMembers();
                }
            };

            // Setup private encrypted channel
            void GeneralListener(string eventName, PusherEvent eventData)
            {
                if (eventName == "secret-event")
                {
                    ChatMessage data = JsonConvert.DeserializeObject <ChatMessage>(eventData.Data);
                    Console.WriteLine($"{Environment.NewLine}[{data.Name}] {data.Message}");
                }
            }

            void DecryptionErrorHandler(object sender, PusherException error)
            {
                if (error is ChannelDecryptionException exception)
                {
                    string errorMsg = $"{Environment.NewLine}Decryption of message failed";
                    errorMsg += $" for ('{exception.ChannelName}',";
                    errorMsg += $" '{exception.EventName}', ";
                    errorMsg += $" '{exception.SocketID}')";
                    errorMsg += $" for reason:{Environment.NewLine}{error.Message}";
                    Console.WriteLine(errorMsg);
                }
            }

            _pusher.Error += DecryptionErrorHandler;
            _pusher.BindAll(GeneralListener);

            _pusher.Connected += (sender) =>
            {
                /*
                 * Setting up subscriptions here is handy if your App has the following setting -
                 * "Enable authorized connections". See https://pusher.com/docs/channels/using_channels/authorized-connections.
                 * If your auth server is not running it will attempt to reconnect approximately every 30 seconds in an attempt to authenticate.
                 * Try running the ExampleApplication and entering your name without running the AuthHost.
                 * You will see it try to authenticate every 30 seconds.
                 * Then run the AuthHost and see the ExampleApplication recover.
                 * Try this experiment again with multiple ExampleApplication instances running.
                 */

                // Subscribe to private channel
                try
                {
                    _chatChannel = _pusher.SubscribeAsync(privateChannelName).Result;
                }
                catch (ChannelUnauthorizedException unauthorizedException)
                {
                    // Handle the authorization failure - forbidden (403)
                    Console.WriteLine($"Authorization failed for {unauthorizedException.ChannelName}. {unauthorizedException.Message}");
                }

                _chatChannel.Bind("client-my-event", (PusherEvent eventData) =>
                {
                    ChatMessage data = JsonConvert.DeserializeObject <ChatMessage>(eventData.Data);
                    Console.WriteLine($"{Environment.NewLine}[{data.Name}] {data.Message}");
                });

                // Subscribe to presence channel
                try
                {
                    _presenceChannel = (GenericPresenceChannel <ChatMember>)(_pusher.SubscribePresenceAsync <ChatMember>(presenceChannelName).Result);
                }
                catch (ChannelUnauthorizedException unauthorizedException)
                {
                    // Handle the authorization failure - forbidden (403)
                    Console.WriteLine($"Authorization failed for {unauthorizedException.ChannelName}. {unauthorizedException.Message}");
                }

                _presenceChannel.MemberAdded   += PresenceChannel_MemberAdded;
                _presenceChannel.MemberRemoved += PresenceChannel_MemberRemoved;

                // Subcribe to private encrypted channel
                try
                {
                    _pusher.SubscribeAsync("private-encrypted-channel").Wait();
                }
                catch (ChannelUnauthorizedException unauthorizedException)
                {
                    // Handle the authorization failure - forbidden (403)
                    Console.WriteLine($"Authorization failed for {unauthorizedException.ChannelName}. {unauthorizedException.Message}");
                }
            };

            await _pusher.ConnectAsync().ConfigureAwait(false);
        }
        private async Task DynamicEventEmitterUnbindTestAsync(ChannelTypes channelType, IList <int> listenersToUnbind)
        {
            // Arrange
            Pusher  localPusher      = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients);
            string  testEventName    = "client-dynamic-event-test";
            dynamic dynamicEventData = CreateDynamicEventData();
            string  channelName      = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);

            string[]         testEventNames       = new string[] { testEventName, testEventName, testEventName, testEventName, };
            AutoResetEvent[] receivedEvents       = new AutoResetEvent[testEventNames.Length];
            int[]            numberEventsReceived = new int[testEventNames.Length];
            int[]            totalEventsExpected  = new int[testEventNames.Length];
            bool[]           eventExpected        = new bool[testEventNames.Length];
            for (int i = 0; i < testEventNames.Length; i++)
            {
                receivedEvents[i]       = new AutoResetEvent(false);
                numberEventsReceived[i] = 0;
                eventExpected[i]        = true;
                if (listenersToUnbind.Contains(i))
                {
                    totalEventsExpected[i] = 1;
                }
                else
                {
                    totalEventsExpected[i] = 2;
                }
            }

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel remoteChannel = await _remoteClient.SubscribeAsync(channelName).ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(channelName).ConfigureAwait(false);

            void Listener(int index, dynamic eventData)
            {
                string eventName = eventData.@event;

                if (eventName == testEventNames[index])
                {
                    numberEventsReceived[index]++;
                    if (eventExpected[index])
                    {
                        receivedEvents[index].Set();
                    }
                }
            }

            void GeneralListener0(string eventName, dynamic eventData)
            {
                Listener(0, eventData);
            }

            void GeneralListener1(string eventName, dynamic eventData)
            {
                Listener(1, eventData);
            }

            void Listener2(dynamic eventData)
            {
                Listener(2, eventData);
            }

            void Listener3(dynamic eventData)
            {
                Listener(3, eventData);
            }

            localPusher.BindAll(GeneralListener0);
            localPusher.BindAll(GeneralListener1);
            localChannel.Bind(testEventName, Listener2);
            localChannel.Bind(testEventName, Listener3);
            await remoteChannel.TriggerAsync(testEventName, dynamicEventData).ConfigureAwait(false);

            for (int i = 0; i < testEventNames.Length; i++)
            {
                Assert.IsTrue(receivedEvents[i].WaitOne(TimeSpan.FromSeconds(5)), $"receivedEvents[{i}]");
                receivedEvents[i].Reset();
            }

            TimeSpan delayAfterTrigger = TimeSpan.FromMilliseconds(0);

            foreach (int index in listenersToUnbind)
            {
                eventExpected[index] = false;
            }

            // Act
            if (listenersToUnbind.Count == testEventNames.Length)
            {
                // Not expecting any events, so wait a bit and ensure that none come in.
                delayAfterTrigger = TimeSpan.FromMilliseconds(500);
                localPusher.UnbindAll();
                localChannel.UnbindAll();
            }
            else
            {
                if (listenersToUnbind.Contains(0))
                {
                    localPusher.Unbind(GeneralListener0);
                }
                if (listenersToUnbind.Contains(1))
                {
                    localPusher.Unbind(GeneralListener1);
                }
                if (listenersToUnbind.Contains(2) && listenersToUnbind.Contains(3))
                {
                    localChannel.Unbind(testEventName);
                }
                else
                {
                    if (listenersToUnbind.Contains(2))
                    {
                        localChannel.Unbind(testEventName, Listener2);
                    }
                    if (listenersToUnbind.Contains(3))
                    {
                        localChannel.Unbind(testEventName, Listener3);
                    }
                }
            }

            await remoteChannel.TriggerAsync(testEventName, dynamicEventData).ConfigureAwait(false);

            await Task.Delay(delayAfterTrigger).ConfigureAwait(false);

            // Assert
            for (int i = 0; i < testEventNames.Length; i++)
            {
                if (eventExpected[i])
                {
                    Assert.IsTrue(receivedEvents[i].WaitOne(TimeSpan.FromSeconds(5)), $"receivedEvents[{i}]");
                }

                Assert.AreEqual(totalEventsExpected[i], numberEventsReceived[i], $"# Event[{i}]");
            }
        }
        private async Task PusherEventEmitterTestAsync(ChannelTypes channelType, bool raiseEmitterActionError = false)
        {
            // Arrange
            Pusher          localPusher                = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients);
            string          testEventName              = "client-pusher-event-test";
            AutoResetEvent  globalEventReceived        = new AutoResetEvent(false);
            AutoResetEvent  channelEventReceived       = new AutoResetEvent(false);
            AutoResetEvent  globalActionErrorReceived  = raiseEmitterActionError ? new AutoResetEvent(false) : null;
            AutoResetEvent  channelActionErrorReceived = raiseEmitterActionError ? new AutoResetEvent(false) : null;
            string          globalActionErrorMsg       = "Simulate error in BindAll action.";
            string          channelActionErrorMsg      = "Simulate error in Bind action.";
            PusherException globalActionError          = null;
            EventEmitterActionException <PusherEvent> channelActionError = null;
            PusherEvent globalEvent  = null;
            PusherEvent channelEvent = null;
            PusherEvent pusherEvent  = CreatePusherEvent(channelType, testEventName);

            if (raiseEmitterActionError)
            {
                void HandleError(object sender, PusherException error)
                {
                    if (error.Message == globalActionErrorMsg)
                    {
                        globalActionError = error;
                        globalActionErrorReceived?.Set();
                    }
                    else if (error.Message.Contains(channelActionErrorMsg))
                    {
                        channelActionError = error as EventEmitterActionException <PusherEvent>;
                        channelActionErrorReceived?.Set();
                    }

                    if (raiseEmitterActionError)
                    {
                        throw new InvalidOperationException("Simulated error from error handler.");
                    }
                }

                localPusher.Error += HandleError;
            }

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel remoteChannel = await _remoteClient.SubscribeAsync(pusherEvent.ChannelName).ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(pusherEvent.ChannelName).ConfigureAwait(false);

            void GeneralListener(string eventName, PusherEvent eventData)
            {
                if (eventName == testEventName)
                {
                    globalEvent = eventData;
                    globalEventReceived.Set();
                    if (raiseEmitterActionError)
                    {
                        throw new PusherException(globalActionErrorMsg, ErrorCodes.Unknown);
                    }
                }
            }

            void Listener(PusherEvent eventData)
            {
                channelEvent = eventData;
                channelEventReceived.Set();
                if (raiseEmitterActionError)
                {
                    throw new InvalidOperationException(channelActionErrorMsg);
                }
            }

            // Act
            localPusher.BindAll(GeneralListener);
            localChannel.Bind(testEventName, Listener);
            remoteChannel.Trigger(testEventName, pusherEvent.Data);

            // Assert
            Assert.IsTrue(globalEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            Assert.IsTrue(channelEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            if (raiseEmitterActionError)
            {
                Assert.IsTrue(globalActionErrorReceived.WaitOne(TimeSpan.FromSeconds(5)));
                Assert.IsTrue(channelActionErrorReceived.WaitOne(TimeSpan.FromSeconds(5)));
                Assert.IsNotNull(globalActionError);
                Assert.IsNotNull(channelActionError);
                Assert.AreEqual(ErrorCodes.EventEmitterActionError, channelActionError.PusherCode);
                Assert.IsNotNull(channelActionError.EventData);
                Assert.AreEqual(testEventName, channelActionError.EventName);
            }

            AssertPusherEventsAreEqual(channelType, pusherEvent, globalEvent);
            AssertPusherEventsAreEqual(channelType, pusherEvent, channelEvent);
        }
        public async Task PusherEventEmitterPrivateEncryptedChannelDecryptionFailureTestAsync()
        {
            // Arrange
            var pusherServer = new PusherServer.Pusher(Config.AppId, Config.AppKey, Config.AppSecret, new PusherServer.PusherOptions
            {
                Cluster             = Config.Cluster,
                EncryptionMasterKey = GenerateEncryptionMasterKey(),
            });

            ChannelDecryptionException decryptionException = null;
            ChannelTypes channelType = ChannelTypes.PrivateEncrypted;

            // Use a different encryption master key - decryption should fail
            Pusher         localPusher          = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients, encryptionKey: GenerateEncryptionMasterKey());
            string         testEventName        = "private-encrypted-event-test";
            AutoResetEvent globalEventReceived  = new AutoResetEvent(false);
            AutoResetEvent channelEventReceived = new AutoResetEvent(false);
            AutoResetEvent errorReceived        = new AutoResetEvent(false);
            PusherEvent    pusherEvent          = CreatePusherEvent(channelType, testEventName);

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(pusherEvent.ChannelName).ConfigureAwait(false);

            void GeneralListener(string eventName, PusherEvent eventData)
            {
                if (eventName == testEventName)
                {
                    globalEventReceived.Set();
                }
            }

            void Listener(PusherEvent eventData)
            {
                channelEventReceived.Set();
            }

            EventTestData data = new EventTestData
            {
                TextField    = ExpectedTextField,
                IntegerField = ExpectedIntegerField,
            };

            void ErrorHandler(object sender, PusherException error)
            {
                decryptionException = error as ChannelDecryptionException;
                if (decryptionException != null)
                {
                    errorReceived.Set();
                }
            }

            // Act
            localPusher.Error += ErrorHandler;
            localPusher.BindAll(GeneralListener);
            localChannel.Bind(testEventName, Listener);
            await pusherServer.TriggerAsync(pusherEvent.ChannelName, testEventName, data).ConfigureAwait(false);

            // Assert
            Assert.IsTrue(errorReceived.WaitOne(TimeSpan.FromSeconds(5)), "Expected to handle an error.");
            Assert.IsNotNull(decryptionException.SocketID, nameof(decryptionException.SocketID));
            Assert.AreEqual(testEventName, decryptionException.EventName, nameof(decryptionException.EventName));
            Assert.AreEqual(localChannel.Name, decryptionException.ChannelName, nameof(decryptionException.ChannelName));
            Assert.IsFalse(globalEventReceived.WaitOne(TimeSpan.FromSeconds(0.1)), "Did not expect to get a global event raised.");
            Assert.IsFalse(channelEventReceived.WaitOne(TimeSpan.FromSeconds(0.1)), "Did not expect to get a channel event raised.");
        }