private Channel CreateChannel(string channelName) { ChannelTypes type = Channel.GetChannelType(channelName); Channel result; switch (type) { case ChannelTypes.Private: case ChannelTypes.PrivateEncrypted: AuthEndpointCheck(channelName); result = new PrivateChannel(channelName, this); break; case ChannelTypes.Presence: AuthEndpointCheck(channelName); result = new PresenceChannel(channelName, this); break; default: result = new Channel(channelName, this); break; } if (!Channels.TryAdd(channelName, result)) { result = Channels[channelName]; } return(result); }
/// <summary> /// Subscribes to a typed member info presence channel. /// </summary> /// <typeparam name="MemberT">The type used to deserialize channel member info.</typeparam> /// <param name="channelName">The name of the channel to subsribe to.</param> /// <param name="subscribedEventHandler">An optional <see cref="SubscriptionEventHandler"/>. Alternatively, use <c>Pusher.Subscribed</c>.</param> /// <exception cref="ArgumentNullException">If <paramref name="channelName"/> is <c>null</c> or whitespace.</exception> /// <exception cref="ChannelUnauthorizedException">If authorization fails.</exception> /// <exception cref="ChannelAuthorizationFailureException">f an HTTP call to the authorization URL fails; that is, the HTTP status code is outside of the range 200-299.</exception> /// <exception cref="ChannelException">If the client receives an error (pusher:error) from the Pusher cluster while trying to subscribe.</exception> /// <exception cref="OperationTimeoutException"> /// If the client times out waiting for the Pusher server to confirm the subscription. The timeout is defind in the <see cref="PusherOptions"/>. /// </exception> /// <returns>A GenericPresenceChannel<MemberT> channel identified by <paramref name="channelName"/>.</returns> /// <remarks> /// If Pusher is connected when calling this method, the channel will be subscribed when this method returns; /// that is <c>channel.IsSubscribed == true</c>. /// If Pusher is not connected when calling this method, <c>channel.IsSubscribed == false</c> and /// the channel will only be subscribed after calling <c>Pusher.ConnectAsync</c>. /// </remarks> public async Task <GenericPresenceChannel <MemberT> > SubscribePresenceAsync <MemberT>( string channelName, SubscriptionEventHandler subscribedEventHandler = null) { Guard.ChannelName(channelName); var channelType = Channel.GetChannelType(channelName); if (channelType != ChannelTypes.Presence) { throw new ArgumentException($"The channel name '{channelName}' is not that of a presence channel. Expecting the name to start with '{Constants.PRESENCE_CHANNEL}'.", nameof(channelName)); } GenericPresenceChannel <MemberT> result; if (Channels.TryGetValue(channelName, out Channel channel)) { if (!(channel is GenericPresenceChannel <MemberT> presenceChannel)) { string errorMsg; if (channel is PresenceChannel) { errorMsg = $"The presence channel '{channelName}' has already been created as a {nameof(PresenceChannel)} : {nameof(PresenceChannel)}<dynamic>."; } else { errorMsg = $"The presence channel '{channelName}' has already been created but with a different type: {channel.GetType()}"; } throw new ChannelException(errorMsg, ErrorCodes.PresenceChannelAlreadyDefined, channelName, SocketID); } if (presenceChannel.IsSubscribed) { result = presenceChannel; } else { result = (await SubscribeAsync(channelName, presenceChannel, subscribedEventHandler).ConfigureAwait(false)) as GenericPresenceChannel <MemberT>; } } else { AuthEndpointCheck(channelName); result = new GenericPresenceChannel <MemberT>(channelName, this); if (Channels.TryAdd(channelName, result)) { result = (await SubscribeAsync(channelName, result, subscribedEventHandler).ConfigureAwait(false)) as GenericPresenceChannel <MemberT>; } } return(result); }
private void ValidateTriggerInput(string channelName, string eventName) { if (Channel.GetChannelType(channelName) == ChannelTypes.Public) { string errorMsg = $"Failed to trigger event '{eventName}'. Client events are only supported on private (non-encrypted) and presence channels."; throw new TriggerEventException(errorMsg, ErrorCodes.TriggerEventPublicChannelError); } if (Channel.GetChannelType(channelName) == ChannelTypes.PrivateEncrypted) { string errorMsg = $"Failed to trigger event '{eventName}'. Client events are not supported on private encrypted channels."; throw new TriggerEventException(errorMsg, ErrorCodes.TriggerEventPrivateEncryptedChannelError); } string token = "client-"; if (eventName.IndexOf(token, StringComparison.OrdinalIgnoreCase) != 0) { string errorMsg = $"Failed to trigger event '{eventName}'. Client events must start with '{token}'."; throw new TriggerEventException(errorMsg, ErrorCodes.TriggerEventNameInvalidError); } if (State != ConnectionState.Connected) { string errorMsg = $"Failed to trigger event '{eventName}'. Client needs to be connected. Current connection state is {State}."; throw new TriggerEventException(errorMsg, ErrorCodes.TriggerEventNotConnectedError); } bool subscribed = false; if (Channels.TryGetValue(channelName, out Channel channel)) { subscribed = channel.IsSubscribed; } if (!subscribed) { string errorMsg = $"Failed to trigger event '{eventName}'. Channel '{channelName}' needs to be subscribed."; throw new TriggerEventException(errorMsg, ErrorCodes.TriggerEventNotSubscribedError); } }