public async Task SubscribeThenConnectPresenceChannelAsync() { #region Code snippet // Create client Pusher pusher = new Pusher(Config.AppKey, new PusherOptions { Authorizer = new FakeAuthoriser(), Cluster = Config.Cluster, }); pusher.Error += ErrorHandler; // Lists all current presence channel members void ListMembers(GenericPresenceChannel <ChatMember> channel) { Dictionary <string, ChatMember> members = channel.GetMembers(); foreach (var member in members) { Trace.TraceInformation($"Id: {member.Key}, Name: {member.Value.Name}"); } } // MemberAdded event handler void ChatMemberAdded(object sender, KeyValuePair <string, ChatMember> member) { Trace.TraceInformation($"Member {member.Value.Name} has joined"); ListMembers(sender as GenericPresenceChannel <ChatMember>); } // MemberRemoved event handler void ChatMemberRemoved(object sender, KeyValuePair <string, ChatMember> member) { Trace.TraceInformation($"Member {member.Value.Name} has left"); ListMembers(sender as GenericPresenceChannel <ChatMember>); } // Subscribe GenericPresenceChannel <ChatMember> memberChannel = await pusher.SubscribePresenceAsync <ChatMember>("presence-channel-1").ConfigureAwait(false); memberChannel.MemberAdded += ChatMemberAdded; memberChannel.MemberRemoved += ChatMemberRemoved; Assert.AreEqual(false, memberChannel.IsSubscribed); // Connect await pusher.ConnectAsync().ConfigureAwait(false); #endregion Code snippet await pusher.DisconnectAsync().ConfigureAwait(false); }
// 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 static void CheckIfAllMembersAdded(int numberOfMembers, ConcurrentDictionary <int, int> membersAddedCounter, AutoResetEvent memberAddedEvent, GenericPresenceChannel <FakeUserInfo> presenceChannel) { int channelId = presenceChannel.GetHashCode(); Dictionary <string, FakeUserInfo> members = presenceChannel.GetMembers(); int savedCount = 0; if (!membersAddedCounter.TryAdd(channelId, members.Count)) { savedCount = membersAddedCounter[channelId]; } if (members.Count > savedCount) { membersAddedCounter[channelId] = members.Count; if (members.Count == numberOfMembers) { bool done = true; foreach (int memberCount in membersAddedCounter.Values) { if (memberCount != numberOfMembers) { done = false; break; } } if (done) { memberAddedEvent.Set(); } } } }
public async Task ApiOverviewAsync() { #region API Overview // Raised when Pusher is ready AutoResetEvent readyEvent = new AutoResetEvent(false); // Raised when Pusher is done AutoResetEvent doneEvent = new AutoResetEvent(false); // Create Pusher client ready to subscribe to public, private and presence channels Pusher pusher = new Pusher(Config.AppKey, new PusherOptions { Authorizer = new FakeAuthoriser(), Cluster = Config.Cluster, Encrypted = true, }); // Lists all current presence channel members void ListMembers(GenericPresenceChannel <ChatMember> channel) { Dictionary <string, ChatMember> members = channel.GetMembers(); foreach (var member in members) { Trace.TraceInformation($"Id: {member.Key}, Name: {member.Value.Name}"); } } // MemberAdded event handler void ChatMemberAdded(object sender, KeyValuePair <string, ChatMember> member) { Trace.TraceInformation($"Member {member.Value.Name} has joined"); if (sender is GenericPresenceChannel <ChatMember> channel) { ListMembers(channel); } } // MemberRemoved event handler void ChatMemberRemoved(object sender, KeyValuePair <string, ChatMember> member) { Trace.TraceInformation($"Member {member.Value.Name} has left"); if (sender is GenericPresenceChannel <ChatMember> channel) { ListMembers(channel); } } // Handle errors void HandleError(object sender, PusherException error) { if ((int)error.PusherCode < 5000) { // Error recevied from Pusher cluster, use PusherCode to filter. } else { if (error is ChannelUnauthorizedException unauthorizedAccess) { // Private and Presence channel failed authorization with Forbidden (403) } else if (error is ChannelAuthorizationFailureException httpError) { // Authorization endpoint returned an HTTP error other than Forbidden (403) } else if (error is OperationTimeoutException timeoutError) { // A client operation has timed-out. Governed by PusherOptions.ClientTimeout } else if (error is ChannelDecryptionException decryptionError) { // Failed to decrypt the data for a private encrypted channel } else { // Handle other errors } } Trace.TraceError($"{error}"); } // Subscribed event handler void SubscribedHandler(object sender, Channel channel) { if (channel is GenericPresenceChannel <ChatMember> presenceChannel) { ListMembers(presenceChannel); } else if (channel.Name == "private-chat-channel-1") { // Trigger event channel.Trigger("client-chat-event", new ChatMessage { Name = "Joe", Message = "Hello from Joe!", }); } } // Connection state change event handler void StateChangedEventHandler(object sender, ConnectionState state) { Trace.TraceInformation($"SocketId: {((Pusher)sender).SocketID}, State: {state}"); if (state == ConnectionState.Connected) { readyEvent.Set(); readyEvent.Reset(); } if (state == ConnectionState.Disconnected) { doneEvent.Set(); doneEvent.Reset(); } } // Bind events void BindEvents(object sender) { Pusher _pusher = sender as Pusher; Channel _channel = _pusher.GetChannel("private-chat-channel-1"); _channel.Bind("client-chat-event", (PusherEvent eventData) => { ChatMessage data = JsonConvert.DeserializeObject <ChatMessage>(eventData.Data); Trace.TraceInformation($"[{data.Name}] {data.Message}"); }); } // Unbind events void UnbindEvents(object sender) { ((Pusher)sender).UnbindAll(); } // Add event handlers pusher.Connected += BindEvents; pusher.Disconnected += UnbindEvents; pusher.Subscribed += SubscribedHandler; pusher.ConnectionStateChanged += StateChangedEventHandler; pusher.Error += HandleError; // Create subscriptions await pusher.SubscribeAsync("public-channel-1").ConfigureAwait(false); await pusher.SubscribeAsync("private-chat-channel-1").ConfigureAwait(false); GenericPresenceChannel <ChatMember> memberChannel = await pusher.SubscribePresenceAsync <ChatMember>("presence-channel-1").ConfigureAwait(false); memberChannel.MemberAdded += ChatMemberAdded; memberChannel.MemberRemoved += ChatMemberRemoved; // Connect try { await pusher.ConnectAsync().ConfigureAwait(false); } catch (Exception) { // We failed to connect, handle the error. // You will also receive the error via // HandleError(object sender, PusherException error) throw; } Assert.AreEqual(ConnectionState.Connected, pusher.State); Assert.IsTrue(readyEvent.WaitOne(TimeSpan.FromSeconds(5))); // Remove subscriptions await pusher.UnsubscribeAllAsync().ConfigureAwait(false); // Disconnect await pusher.DisconnectAsync().ConfigureAwait(false); Assert.AreEqual(ConnectionState.Disconnected, pusher.State); Assert.IsTrue(doneEvent.WaitOne(TimeSpan.FromSeconds(5))); #endregion API Overview }