Subject: Timing Issue with Setting Subscriptions
We're using MatriX to connect to Finesse and are experiencing an issue where some users intermittently get an error after logging in. Outside the intermittent error, everything seems to work fine.
The error is:
And occurs if we make a call to PubSubManager.SubscribeAsync or PubSubManager.UnsubscribeAsync in the OnPresence event.
We were able to reproduce the issue with a simplified version of the code in a console app:
The error is:
- <error code="400" type="wait" xmlns="jabber:client">
- <unexpected-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
- <not-subscribed xmlns="http://jabber.org/protocol/pubsub#errors" />
- </error>
And occurs if we make a call to PubSubManager.SubscribeAsync or PubSubManager.UnsubscribeAsync in the OnPresence event.
We were able to reproduce the issue with a simplified version of the code in a console app:
- static void Main(string[] args)
- {
- {
- client.SetXmppDomain(domain);
- client.SetUsername(agentId);
- client.Password = agentId;
- client.OnError += XmppClient_OnError;
- client.OnPresence += Client_OnPresence;
- client.Open();
- Console.WriteLine("Listening... Press any key to terminate");
- Console.ReadKey();
- client.Close();
- }
- }
- private static async void Client_OnPresence(object sender, PresenceEventArgs e)
- {
- if (isSubscriptionsSet)
- return;
- isSubscriptionsSet = true;
- try
- {
- var subNodes = GetNodesToSubscribeTo();
- await mgr.ConfigureInitialSubscriptions(subNodes.ToList());
- Console.WriteLine("Subscriptions set");
- }
- catch (Exception ex)
- {
- Write(ex.ToString());
- Console.WriteLine("Subscriptions set");
- }
- }
- internal class PubsubSubscriptionManager
- {
- private readonly PubSubManager psManager;
- private readonly Jid pubsubJid;
- private readonly Jid userJid;
- public PubsubSubscriptionManager(XmppClient client, string agentId, ICtiEventLogger log)
- {
- }
- public async Task ConfigureInitialSubscriptions(List<FinesseNodePath> desiredSubscriptions)
- {
- var existingSubscriptions = await GetCurrentSubscriptions();
- var missing = desiredSubscriptions.Except(existingSubscriptions);
- var toRemove = existingSubscriptions.Except(desiredSubscriptions);
- foreach (var sub in toRemove)
- {
- var subResult = await psManager.UnsubscribeAsync(pubsubJid, sub.NodeId, userJid);
- if (subResult.Type != IqType.Result)// Error occurs here
- {
- }
- }
- foreach (var sub in missing)
- {
- var subResult = await psManager.SubscribeAsync(pubsubJid, sub.NodeId, userJid);
- if (subResult.Type != IqType.Result)// Error occurs here
- {
- }
- }
- }
- private async Task<List<FinesseNodePath>> GetCurrentSubscriptions()
- {
- var subResp = await psManager.RequestSubscriptionsAsync(pubsubJid, null);
- if (subResp.Error != null)
- var pubSubData = subResp.Element<PubSub>();
- var subList = pubSubData.Subscriptions.Elements<Subscription>();
- var result = subList.Select(x => FinesseNodePath.FromPath(x.Node)).ToList();
- return result;
- }
- }