Not logged in. · Lost password · Register
Forum: MatriX RSS
Avatar
PTEC3D70 #1
Member since Dec 2013 · 6 posts
Group memberships: Members
Show profile · Link to this post
Subject: Reconnect sample with backup server and OnBind event
We have modified the reconnect example to use a backup server (see source code at the end of the message)

We have to add a connection timeout timer to handle a case where we never receive the onBind event.
This case is not systematic, but with no timeout it blocks the process !

The timeout is not the best solution : we lose time to detect the error (2 min)

Do you have an idea why the onBind event sometimes never comes or a best way to handle this issue ?

The log when it is ok and when it happens :

// Connect to 1st server
13:48:00 : 0 : connect: XMPP connecting....
13:48:00 : 0 : Using host : server1.e-i.net
13:48:00 : 0 : OnLogin

// Connection Ok
13:48:00 : 0 : OnBind: XMPP connected. JID: user@e-i.net/other0 :

// Reboot server 1
14:14:55 : 0 : OnStreamError: error condition SystemShutdown
14:14:55 : 0 : OnClose: XMPP connection closed
14:14:55 : 0 : starting reconnect timer...

// Connect to 2nd server
14:15:00 : 0 : connect: XMPP connecting....
14:15:00 : 0 : Using host : server2.e-i.net
14:15:00 : 0 : OnLogin
14:15:00 : 0 : OnBind: XMPP connected. JID: user@e-i.net/other0 :

// No problem

// Reboot server 2
15:49:56 : 0 : OnStreamError: error condition SystemShutdown
15:49:56 : 0 : OnClose: XMPP connection closed
15:49:56 : 0 : starting reconnect timer...

// Connect to 1st server
15:50:01 : 0 : connect: XMPP connecting....
15:50:01 : 0 : Using host : server1.e-i.net
15:50:02 : 0 : OnLogin

// We never received OnBindEvent (or another event !)
// => 2min timeout timer launched to close the connection

15:52:01 : 0 : OnClose: XMPP connection closed

// Connect to 2nd server
15:52:01 : 0 : starting reconnect timer...
15:52:06 : 0 : connect: XMPP connecting....
15:52:06 : 0 : Using host : server2.e-i.net

// Reboot not finished => fail
15:52:11 : 0 : OnError: ClientSocket Connection request failed.

// Retry to 1st server
15:52:11 : 0 : starting reconnect timer...
15:52:16 : 0 : connect: XMPP connecting....
15:52:16 : 0 : Using host : server1.e-i.net
15:52:17 : 0 : OnLogin

//  Connection Ok !
15:52:17 : 0 : OnBind: XMPP connected. JID: user@e-i.net/other0 :

Program.cs :

  1. using System;
  2.  
  3. namespace Reconnect
  4. {
  5.     class Program
  6.     {
  7.         static void Main(string[] args)
  8.         {
  9.             Matrix.License.LicenseManager.SetLicense(@"key");
  10.            
  11.             ReconnectXmppWrapper [] rxwa = new ReconnectXmppWrapper [1];
  12.  
  13.             for (int i = 0; i < rxwa.Length; i++ )
  14.             {
  15.                 rxwa[i] = new ReconnectXmppWrapper("e-i.net", "USER", "PASSWORD", i);
  16.                 rxwa[i].Connect(null);
  17.             }
  18.             Console.WriteLine("press any key to stop");
  19.             Console.ReadLine();
  20.         }
  21.     }
  22. }

ReconnectXmppWrapper.cs :

  1. using System;
  2. using System.Threading;
  3. using Matrix.Xmpp.Client;
  4.  
  5. namespace Reconnect
  6. {
  7.     public class ReconnectXmppWrapper
  8.     {
  9.         XmppClient xmppClient;
  10.         bool onLogin;
  11.         Timer connectTimer;
  12.         TimerCallback connectTimerCallback;
  13.         string m_i;
  14.        
  15.         string []host = {"server1.e-i.net","serveur2.e-i.net"};
  16.         int ihost = 0;
  17.        
  18.         public ReconnectXmppWrapper(string xmppdomain, string username, string password, int i)
  19.         {
  20.             m_i = i.ToString() + " : ";
  21.  
  22.             xmppClient = new XmppClient
  23.             {
  24.                 XmppDomain = xmppdomain,
  25.                 Username = username,
  26.                 Password = password
  27.             };
  28.  
  29.  
  30.             xmppClient.ResolveSrvRecords = false;
  31.             xmppClient.Port = 5222;
  32.             xmppClient.Resource = "other" + m_i;
  33.             xmppClient.AutoPresence = false;
  34.  
  35.             xmppClient.OnMessage += OnMessage;
  36.             xmppClient.OnClose += OnClose;
  37.             xmppClient.OnBind += OnBind;
  38.             xmppClient.OnBindError += OnBindError;
  39.             xmppClient.OnAuthError += OnAuthError;
  40.             xmppClient.OnError += OnError;
  41.             xmppClient.OnStreamError += OnStreamError;
  42.             xmppClient.OnXmlError += OnXmlError;
  43.             xmppClient.OnLogin += OnLogin;
  44.  
  45.             connectTimerCallback = Connect;
  46.             connectTimer = new Timer(connectTimerCallback);
  47.  
  48.             connectTimeoutTimerCallback = ConnectTimeout;
  49.             connectTimeoutTimer = new Timer(connectTimeoutTimerCallback);
  50.         }
  51.      
  52.  
  53.         #region xmpp error handlers
  54.         private void OnBindError(object sender, IqEventArgs e)
  55.         {
  56.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnBindError" + e.Iq.Error);
  57.             xmppClient.Close();
  58.         }
  59.  
  60.         private void OnStreamError(object sender, Matrix.StreamErrorEventArgs e)
  61.         {
  62.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnStreamError: error condition " + e.Error.Condition.ToString());
  63.         }
  64.  
  65.         private void OnXmlError(object sender, Matrix.ExceptionEventArgs e)
  66.         {
  67.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnXmlError");
  68.             Console.WriteLine(e.Exception.Message);
  69.             Console.WriteLine(e.Exception.StackTrace);
  70.         }
  71.        
  72.         private void OnAuthError(object sender, Matrix.Xmpp.Sasl.SaslEventArgs e)
  73.         {
  74.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnAuthError");
  75.         }
  76.  
  77.         private void OnError(object sender, Matrix.ExceptionEventArgs e)
  78.         {
  79.             string msg = (e != null ? (e.Exception != null ? e.Exception.Message : "") : "");
  80.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnError: " + msg);
  81.            
  82.             if (!onLogin)
  83.             {
  84.                 StartConnectTimer();
  85.             }
  86.         }
  87.         #endregion
  88.  
  89.         #region << XMPP handlers >>
  90.  
  91.         private void OnLogin(object sender, Matrix.EventArgs e)
  92.         {
  93.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnLogin");
  94.             onLogin = true;
  95.         }
  96.  
  97.         private void OnMessage(object sender, MessageEventArgs e)
  98.         {
  99.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + String.Format("Message from {0}: {1} ", e.Message.From, e.Message.Body));
  100.         }
  101.  
  102.         private void OnBind(object sender, Matrix.JidEventArgs e)
  103.         {
  104.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnBind: XMPP connected. JID: " + e.Jid);
  105.  
  106.             // Stop connection Timeout
  107.             connectTimeoutTimer.Change(Timeout.Infinite, Timeout.Infinite);
  108.         }
  109.  
  110.         private void OnClose(object sender, Matrix.EventArgs e)
  111.         {
  112.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "OnClose: XMPP connection closed");
  113.             StartConnectTimer();
  114.         }
  115.         #endregion
  116.  
  117.         TimerCallback connectTimeoutTimerCallback;
  118.         Timer connectTimeoutTimer;
  119.  
  120.         public const int ConnectTimeoutConst = 120000;
  121.        
  122.         public void ConnectTimeout(Object obj)
  123.         {
  124.             xmppClient.Close();
  125.  
  126.             connectTimeoutTimer.Change(Timeout.Infinite, Timeout.Infinite);
  127.         }
  128.  
  129.         private void StartConnectTimer()
  130.         {
  131.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "starting reconnect timer...");
  132.            
  133.             // Stop connection Timeout
  134.             connectTimeoutTimer.Change(Timeout.Infinite, Timeout.Infinite);
  135.             connectTimer.Change(5000, Timeout.Infinite);
  136.         }
  137.  
  138.         public void Connect(Object obj)
  139.         {
  140.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "connect: XMPP connecting.... ");
  141.             onLogin = false;
  142.  
  143.             // switch server
  144.             xmppClient.Hostname = host[ihost++];
  145.             if (ihost >= host.Length) ihost = 0;
  146.  
  147.             Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + " : " + m_i + "Using host : " + xmppClient.Hostname);
  148.  
  149.             xmppClient.Open();
  150.            
  151.             // Start connection Timeout
  152.             connectTimeoutTimer.Change(ConnectTimeoutConst, Timeout.Infinite);
  153.         }
  154.     }
  155. }
This post was edited on 2014-03-14, 11:49 by Alex.
Avatar
Alex #2
Member since Feb 2003 · 4327 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Hello,

in XMPP you can use SRV records for load balancing and fail over. This means all you have to do is add you servers to your SRV records in the DNS with priority and weight. When once is down MatriX will automatically try to connect to the other server.
The logic you have added to the reconnect code is already implemented in MatriX, and much more.

Apart from this I have no idea right now why you don't get the OnBind.
Can you please make sure that you use the latest MatriX version froom here:
http://www.ag-software.net/download-directory/

In one of the latest releases we have optimized the threading and fixed one problem which could cause reconnect problems under some conditions.

When the problem still occurs with the latest build the Xml logs can help to locate a problem. A a complete test case which we can use to reproduce the problem.

Can you see in the logs if your server replies to the Bind Iq request from MatriX?

Alex
Avatar
PTEC3D70 #3
Member since Dec 2013 · 6 posts
Group memberships: Members
Show profile · Link to this post
Hello,

The first tests were made with version 1.5.4.7.
We downloaded the latest version 1.5.5.0.

With this new version we had only 1 timeout and received many times this error message when waiting for the onbind :
OnBindError<error code="409" type="cancel" xmlns="jabber:client"><conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error>
This behaviour is better.

Thanks for your response.
Avatar
Alex #4
Member since Feb 2003 · 4327 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
The conflict error is from you server. It comes when you try to login 2 times with the same resource.
This means you try to login a second time the same user with the same resource.

The other problem was related to the thread you posted a while ago:
http://forum.ag-software.net/thread/1643-Reconnect-sample-…

Didn't you update after this thread?

Alex
Avatar
PTEC3D70 #5
Member since Dec 2013 · 6 posts
Group memberships: Members
Show profile · Link to this post
Hello,

We have updated after the thread.
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Forum: MatriX RSS