diff --git a/src/Api/PubnubApi/EndPoint/PubSub/SubscribeManager.cs b/src/Api/PubnubApi/EndPoint/PubSub/SubscribeManager.cs index a2dcad83a..ba0087a31 100644 --- a/src/Api/PubnubApi/EndPoint/PubSub/SubscribeManager.cs +++ b/src/Api/PubnubApi/EndPoint/PubSub/SubscribeManager.cs @@ -419,6 +419,7 @@ internal void MultiChannelSubscribeInit(PNOperationType responseType, string[ { bool channelGroupSubscribeOnly = false; SubscribeDisconnected[PubnubInstance.InstanceId] = false; + SubscribeAccessDenied[PubnubInstance.InstanceId] = false; if (rawChannels != null && rawChannels.Length > 0) { @@ -555,14 +556,7 @@ internal void MultiChannelSubscribeInit(PNOperationType responseType, string[ ResetInternetCheckSettings(channels, channelGroups); MultiChannelSubscribeRequest(responseType, channels, channelGroups, 0, 0, false, initialSubscribeUrlParams, externalQueryParam); - if (SubscribeHeartbeatCheckTimer != null) - { - try - { - SubscribeHeartbeatCheckTimer.Change(Timeout.Infinite, Timeout.Infinite); - } - catch { /* ignore */ } - } + CheckAndDisableubscribeHeartbeatCheckTimer(); SubscribeHeartbeatCheckTimer = new Timer(StartSubscribeHeartbeatCheckCallback, null, config.SubscribeTimeout * 500, config.SubscribeTimeout * 500); } } @@ -572,6 +566,18 @@ internal void MultiChannelSubscribeInit(PNOperationType responseType, string[ } } + private static void CheckAndDisableubscribeHeartbeatCheckTimer() + { + if (SubscribeHeartbeatCheckTimer != null) + { + try + { + SubscribeHeartbeatCheckTimer.Change(Timeout.Infinite, Timeout.Infinite); + } + catch { /* ignore */ } + } + } + private void MultiChannelSubscribeRequest(PNOperationType type, string[] channels, string[] channelGroups, object timetoken, int region, bool reconnect, Dictionary initialSubscribeUrlParams, Dictionary externalQueryParam) { if (SubscribeDisconnected[PubnubInstance.InstanceId]) @@ -670,9 +676,11 @@ private void MultiChannelSubscribeRequest(PNOperationType type, string[] chan // Wait for message string json = ""; + PNStatus pnStatus = null; UrlProcessRequest(request, pubnubRequestState, false).ContinueWith(r => { json = r.Result.Item1; + pnStatus = r.Result.Item2; }, TaskContinuationOptions.ExecuteSynchronously).Wait(); if (!string.IsNullOrEmpty(json)) { @@ -730,6 +738,22 @@ private void MultiChannelSubscribeRequest(PNOperationType type, string[] chan } else { + if (pnStatus != null && pnStatus.Category == PNStatusCategory.PNAccessDeniedCategory) + { + //Announce 403 and exit subscribe on 403 + Announce(pnStatus); //Announce to subscribe callback when 403 + + ///Disabling flags/checks which can invoke resubscribe + SubscribeAccessDenied[PubnubInstance.InstanceId] = true; + Task.Factory.StartNew(() => + { + TerminateCurrentSubscriberRequest(); + }, CancellationToken.None, TaskCreationOptions.PreferFairness, TaskScheduler.Default).ConfigureAwait(false); + + CheckAndDisableubscribeHeartbeatCheckTimer(); + return; + } + if (multiplexExceptionTimer != null) { multiplexExceptionTimer.Change(Timeout.Infinite, Timeout.Infinite); @@ -1027,6 +1051,12 @@ internal void StartSubscribeHeartbeatCheckCallback(object state) LoggingMethod.WriteToLog(pubnubLog, string.Format("DateTime {0}, SubscribeManager - SubscribeDisconnected. No heartbeat check.", DateTime.Now.ToString(CultureInfo.InvariantCulture)), config.LogVerbosity); return; } + if (SubscribeAccessDenied[PubnubInstance.InstanceId]) + { + CheckAndDisableubscribeHeartbeatCheckTimer(); + LoggingMethod.WriteToLog(pubnubLog, string.Format("DateTime {0}, SubscribeManager - SubscribeAccessDenied. Exiting StartSubscribeHeartbeatCheckCallback.", DateTime.Now.ToString(CultureInfo.InvariantCulture)), config.LogVerbosity); + return; + } string[] channels = GetCurrentSubscriberChannels(); string[] chananelGroups = GetCurrentSubscriberChannelGroups(); diff --git a/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation.cs b/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation.cs index ecf340b6d..11e493e70 100644 --- a/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation.cs +++ b/src/Api/PubnubApi/EndPoint/PubSub/SubscribeOperation.cs @@ -235,6 +235,10 @@ internal void CurrentPubnubInstance(Pubnub instance) { SubscribeDisconnected.GetOrAdd(instance.InstanceId, false); } + if (!SubscribeAccessDenied.ContainsKey(instance.InstanceId)) + { + SubscribeAccessDenied.GetOrAdd(instance.InstanceId, false); + } if (!LastSubscribeTimetoken.ContainsKey(instance.InstanceId)) { LastSubscribeTimetoken.GetOrAdd(instance.InstanceId, 0); diff --git a/src/Api/PubnubApi/PubnubCoreBase.cs b/src/Api/PubnubApi/PubnubCoreBase.cs index ea3e990cc..32ca8d43e 100644 --- a/src/Api/PubnubApi/PubnubCoreBase.cs +++ b/src/Api/PubnubApi/PubnubCoreBase.cs @@ -53,6 +53,7 @@ public abstract class PubnubCoreBase private bool clientNetworkStatusInternetStatus = true; protected static ConcurrentDictionary SubscribeDisconnected { get; set; } = new ConcurrentDictionary(); + protected static ConcurrentDictionary SubscribeAccessDenied { get; set; } = new ConcurrentDictionary(); protected Pubnub PubnubInstance { get; set; } diff --git a/src/Examples/PubnubApi.ConsoleExample/PubnubExample.cs b/src/Examples/PubnubApi.ConsoleExample/PubnubExample.cs index 798f042be..86c816705 100644 --- a/src/Examples/PubnubApi.ConsoleExample/PubnubExample.cs +++ b/src/Examples/PubnubApi.ConsoleExample/PubnubExample.cs @@ -2221,12 +2221,12 @@ static public void Main() .AuthorizedUuid(grantAuthorizedUuiIdEntry) .Resources(new PNTokenResources() { - Channels = new Dictionary() { - { grantChannelName, new PNTokenAuthValues() { Read = grantRead, Write = grantWrite, Manage= grantManage, Create = grantCreate, Delete=grantDelete, Get = grantGet, Update = grantUpdate, Join = grantJoin } } }, - ChannelGroups = new Dictionary() { - {grantChannelGroupName, new PNTokenAuthValues() { Read = grantRead, Write = grantWrite, Manage= grantManage, Create = grantCreate, Delete=grantDelete, Get = grantGet, Update = grantUpdate, Join = grantJoin } } }, - Uuids = new Dictionary() { - { grantUuiIdEntry, new PNTokenAuthValues() { Read = grantRead, Write = grantWrite, Manage= grantManage, Create = grantCreate, Delete=grantDelete, Get = grantGet, Update = grantUpdate, Join = grantJoin } } }, + Channels = !string.IsNullOrEmpty(grantChannelName) ? new Dictionary() { + { grantChannelName, new PNTokenAuthValues() { Read = grantRead, Write = grantWrite, Manage= grantManage, Create = grantCreate, Delete=grantDelete, Get = grantGet, Update = grantUpdate, Join = grantJoin } } } : null, + ChannelGroups = !string.IsNullOrEmpty(grantChannelGroupName) ? new Dictionary() { + {grantChannelGroupName, new PNTokenAuthValues() { Read = grantRead, Write = grantWrite, Manage= grantManage, Create = grantCreate, Delete=grantDelete, Get = grantGet, Update = grantUpdate, Join = grantJoin } } } : null, + Uuids = !string.IsNullOrEmpty(grantUuiIdEntry) ? new Dictionary() { + { grantUuiIdEntry, new PNTokenAuthValues() { Read = grantRead, Write = grantWrite, Manage= grantManage, Create = grantCreate, Delete=grantDelete, Get = grantGet, Update = grantUpdate, Join = grantJoin } } } : null, }) .Execute(new PNAccessManagerTokenResultExt((result, status) => {