You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by Tammer Salem <ta...@googlemail.com> on 2010/05/10 16:04:03 UTC
NMS - cannot recover from connection failure
Hello All,
I have an NMS client using the stomp broker on a .netcf device. For the most
part it works absolutely fine, but now I'm trying to harden the device (for
network failures etc.).
I have added an exception listener and specifically look for IOExceptions
(which I believe are what .NET throws if the GPRS/3G network connectivity
dies). I can successfully capture this exception and then I fire off a
thread to restart the connection and add my listeners again.
At the moment this method doesn't seem to work - I can never get a
connection again. Can anyone advise what is the best way of doing this?
I've also attached my code so that you know what I'm trying to do.
class AMQMessageHandler
{
private String myQueue;
private String connecturi;
//private ISession session;
IConnectionFactory factory;
IConnection connection;
ISession session;
IDestination destination;
IMessageConsumer messageConsumer;
/*
* the UI thread within whose context the code will be executed
*/
private Form uiThread;
> /*
* function in the UI thread to handle exceptions
*/
private Delegate exceptionDelegate;
>
> public AMQMessageHandler(String connectionURI, String driverID,
> Delegate exceptionDelegate, Form uiThread)
{
this.connecturi = connectionURI;
this.myQueue = "driver.channel." + driverID;
this.uiThread = uiThread;
this.exceptionDelegate = exceptionDelegate;
}
> public void start()
{
> try
{
this.factory = new ConnectionFactory(connecturi);
this.connection = this.factory.CreateConnection();
this.session = this.connection.CreateSession();
this.destination = SessionUtil.GetDestination(session,
> "queue://" + myQueue);
this.messageConsumer = session.CreateConsumer(destination);
messageConsumer.Listener += new
> MessageListener(messageConsumer_Listener);
connection.ExceptionListener += new
> ExceptionListener(connection_ExceptionListener);
connection.Start();
> }
catch (Exception ex)
{
uiThread.Invoke(exceptionDelegate,ex.Message);
}
}
> public delegate void RestartConnectionDelegate();
> private void restartConnection()
{
new System.Threading.Thread(threadedStartConnection).Start();
}
> private void threadedStartConnection()
{
int retryCount = 1;
bool keepTryingtoRestart = true;
> while (keepTryingtoRestart == true)
{
//tsalem - add some kind of logging here
//listBox.Items.Add("attempting to reconnect - pass " +
> retryCount);
System.Threading.Thread.Sleep(3000);
> try
{
this.factory = new ConnectionFactory(connecturi);
this.connection = this.factory.CreateConnection();
this.session = this.connection.CreateSession();
this.destination = SessionUtil.GetDestination(session,
> "queue://" + myQueue);
this.messageConsumer =
> session.CreateConsumer(destination);
messageConsumer.Listener += new
> MessageListener(messageConsumer_Listener);
connection.ExceptionListener += new
> ExceptionListener(connection_ExceptionListener);
connection.Start();
> keepTryingtoRestart = false;
}
catch (Exception ex)
{
uiThread.Invoke(exceptionDelegate, ex.Message +"\n" +
> ex.StackTrace);
//tsalem change this to check for keep retrying rather
> than on a counter
if (retryCount == 50)
{
keepTryingtoRestart = false;
}
> }
retryCount++;
}
}
>
> public void messageConsumer_Listener(IMessage receivedMessage)
{
try
{
ITextMessage message = receivedMessage as ITextMessage;
message.Acknowledge();
//tsalem - todo - handle message
if (message.Text != null)
{
AMQUtil.Instance.ResponseAvailable(message.Text,
> uiThread);
}
else
{
uiThread.Invoke(exceptionDelegate, "ERROR: AMQ Message
> is empty");
}
}
catch (Exception ex)
{
uiThread.Invoke(exceptionDelegate,ex.Message);
}
}
>
>
> void connection_ExceptionListener(Exception exception)
{
uiThread.Invoke(exceptionDelegate,exception.Message);
> if (exception is System.IO.IOException)
{
//Invoke(new
> RestartConnectionDelegate(threadedStartConnection));
threadedStartConnection();
}
}
}
regards,
Tammer
Re: NMS - cannot recover from connection failure
Posted by Timothy Bish <ta...@gmail.com>.
On Tue, 2010-05-11 at 00:43 +0100, Tammer Salem wrote:
> Sorry - yes I get an exception stating that it cannot connect to the given
> URI (even though the URI is 100% correct in that block of code). When I shut
> down the client and restart it - it works fine.
>
You could try doing an explicit close on all the NMS.Stomp resources
that you created, session, connection etc before recreating to see if
that frees up a resource that is preventing you from reconnecting to
that same URI.
Regards
Tim.
> On 10 May 2010 21:31, Timothy Bish <ta...@gmail.com> wrote:
>
> > On Mon, 2010-05-10 at 15:04 +0100, Tammer Salem wrote:
> > > Hello All,
> > > I have an NMS client using the stomp broker on a .netcf device. For the
> > most
> > > part it works absolutely fine, but now I'm trying to harden the device
> > (for
> > > network failures etc.).
> > > I have added an exception listener and specifically look for IOExceptions
> > > (which I believe are what .NET throws if the GPRS/3G network connectivity
> > > dies). I can successfully capture this exception and then I fire off a
> > > thread to restart the connection and add my listeners again.
> > >
> > > At the moment this method doesn't seem to work - I can never get a
> > > connection again. Can anyone advise what is the best way of doing this?
> > >
> >
> > So what happens exactly when the code attempts to create the new
> > Connection object and restore the Sessions and Destinations etc? Is
> > there an exception being thrown?
> >
> > Regards
> > Tim.
> >
> >
> > > I've also attached my code so that you know what I'm trying to do.
> > >
> > > class AMQMessageHandler
> > >
> > > {
> > >
> > > private String myQueue;
> > >
> > > private String connecturi;
> > >
> > >
> > >
> > > //private ISession session;
> > >
> > > IConnectionFactory factory;
> > >
> > > IConnection connection;
> > >
> > > ISession session;
> > >
> > > IDestination destination;
> > >
> > > IMessageConsumer messageConsumer;
> > >
> > >
> > >
> > > /*
> > >
> > > * the UI thread within whose context the code will be executed
> > >
> > > */
> > >
> > > private Form uiThread;
> > >
> > >
> > > > /*
> > >
> > > * function in the UI thread to handle exceptions
> > >
> > > */
> > >
> > > private Delegate exceptionDelegate;
> > >
> > >
> > > >
> > > > public AMQMessageHandler(String connectionURI, String driverID,
> > > > Delegate exceptionDelegate, Form uiThread)
> > >
> > > {
> > >
> > > this.connecturi = connectionURI;
> > >
> > > this.myQueue = "driver.channel." + driverID;
> > >
> > > this.uiThread = uiThread;
> > >
> > > this.exceptionDelegate = exceptionDelegate;
> > >
> > > }
> > >
> > >
> > > > public void start()
> > >
> > > {
> > >
> > >
> > > > try
> > >
> > > {
> > >
> > > this.factory = new ConnectionFactory(connecturi);
> > >
> > > this.connection = this.factory.CreateConnection();
> > >
> > > this.session = this.connection.CreateSession();
> > >
> > > this.destination = SessionUtil.GetDestination(session,
> > > > "queue://" + myQueue);
> > >
> > > this.messageConsumer =
> > session.CreateConsumer(destination);
> > >
> > >
> > >
> > > messageConsumer.Listener += new
> > > > MessageListener(messageConsumer_Listener);
> > >
> > > connection.ExceptionListener += new
> > > > ExceptionListener(connection_ExceptionListener);
> > >
> > > connection.Start();
> > >
> > >
> > > > }
> > >
> > > catch (Exception ex)
> > >
> > > {
> > >
> > > uiThread.Invoke(exceptionDelegate,ex.Message);
> > >
> > > }
> > >
> > > }
> > >
> > >
> > > > public delegate void RestartConnectionDelegate();
> > >
> > >
> > > > private void restartConnection()
> > >
> > > {
> > >
> > > new System.Threading.Thread(threadedStartConnection).Start();
> > >
> > > }
> > >
> > >
> > > > private void threadedStartConnection()
> > >
> > > {
> > >
> > > int retryCount = 1;
> > >
> > > bool keepTryingtoRestart = true;
> > >
> > >
> > > > while (keepTryingtoRestart == true)
> > >
> > > {
> > >
> > > //tsalem - add some kind of logging here
> > >
> > > //listBox.Items.Add("attempting to reconnect - pass " +
> > > > retryCount);
> > >
> > > System.Threading.Thread.Sleep(3000);
> > >
> > >
> > > > try
> > >
> > > {
> > >
> > > this.factory = new ConnectionFactory(connecturi);
> > >
> > > this.connection = this.factory.CreateConnection();
> > >
> > > this.session = this.connection.CreateSession();
> > >
> > > this.destination =
> > SessionUtil.GetDestination(session,
> > > > "queue://" + myQueue);
> > >
> > > this.messageConsumer =
> > > > session.CreateConsumer(destination);
> > >
> > > messageConsumer.Listener += new
> > > > MessageListener(messageConsumer_Listener);
> > >
> > > connection.ExceptionListener += new
> > > > ExceptionListener(connection_ExceptionListener);
> > >
> > > connection.Start();
> > >
> > >
> > > > keepTryingtoRestart = false;
> > >
> > > }
> > >
> > > catch (Exception ex)
> > >
> > > {
> > >
> > > uiThread.Invoke(exceptionDelegate, ex.Message +"\n" +
> > > > ex.StackTrace);
> > >
> > > //tsalem change this to check for keep retrying
> > rather
> > > > than on a counter
> > >
> > > if (retryCount == 50)
> > >
> > > {
> > >
> > > keepTryingtoRestart = false;
> > >
> > > }
> > >
> > >
> > > > }
> > >
> > >
> > >
> > > retryCount++;
> > >
> > > }
> > >
> > > }
> > >
> > >
> > > >
> > > > public void messageConsumer_Listener(IMessage receivedMessage)
> > >
> > > {
> > >
> > > try
> > >
> > > {
> > >
> > > ITextMessage message = receivedMessage as ITextMessage;
> > >
> > > message.Acknowledge();
> > >
> > > //tsalem - todo - handle message
> > >
> > > if (message.Text != null)
> > >
> > > {
> > >
> > > AMQUtil.Instance.ResponseAvailable(message.Text,
> > > > uiThread);
> > >
> > > }
> > >
> > > else
> > >
> > > {
> > >
> > > uiThread.Invoke(exceptionDelegate, "ERROR: AMQ
> > Message
> > > > is empty");
> > >
> > > }
> > >
> > > }
> > >
> > > catch (Exception ex)
> > >
> > > {
> > >
> > > uiThread.Invoke(exceptionDelegate,ex.Message);
> > >
> > > }
> > >
> > > }
> > >
> > >
> > > >
> > > >
> > > > void connection_ExceptionListener(Exception exception)
> > >
> > > {
> > >
> > > uiThread.Invoke(exceptionDelegate,exception.Message);
> > >
> > >
> > > > if (exception is System.IO.IOException)
> > >
> > > {
> > >
> > > //Invoke(new
> > > > RestartConnectionDelegate(threadedStartConnection));
> > >
> > > threadedStartConnection();
> > >
> > > }
> > >
> > > }
> > >
> > > }
> > >
> > >
> > > regards,
> > > Tammer
> >
> > --
> > Tim Bish
> >
> > Open Source Integration: http://fusesource.com
> > ActiveMQ in Action: http://www.manning.com/snyder/
> >
> > Follow me on Twitter: http://twitter.com/tabish121
> > My Blog: http://timbish.blogspot.com/
> >
> >
--
Tim Bish
Open Source Integration: http://fusesource.com
ActiveMQ in Action: http://www.manning.com/snyder/
Follow me on Twitter: http://twitter.com/tabish121
My Blog: http://timbish.blogspot.com/
Re: NMS - cannot recover from connection failure
Posted by Tammer Salem <ta...@googlemail.com>.
Sorry - yes I get an exception stating that it cannot connect to the given
URI (even though the URI is 100% correct in that block of code). When I shut
down the client and restart it - it works fine.
On 10 May 2010 21:31, Timothy Bish <ta...@gmail.com> wrote:
> On Mon, 2010-05-10 at 15:04 +0100, Tammer Salem wrote:
> > Hello All,
> > I have an NMS client using the stomp broker on a .netcf device. For the
> most
> > part it works absolutely fine, but now I'm trying to harden the device
> (for
> > network failures etc.).
> > I have added an exception listener and specifically look for IOExceptions
> > (which I believe are what .NET throws if the GPRS/3G network connectivity
> > dies). I can successfully capture this exception and then I fire off a
> > thread to restart the connection and add my listeners again.
> >
> > At the moment this method doesn't seem to work - I can never get a
> > connection again. Can anyone advise what is the best way of doing this?
> >
>
> So what happens exactly when the code attempts to create the new
> Connection object and restore the Sessions and Destinations etc? Is
> there an exception being thrown?
>
> Regards
> Tim.
>
>
> > I've also attached my code so that you know what I'm trying to do.
> >
> > class AMQMessageHandler
> >
> > {
> >
> > private String myQueue;
> >
> > private String connecturi;
> >
> >
> >
> > //private ISession session;
> >
> > IConnectionFactory factory;
> >
> > IConnection connection;
> >
> > ISession session;
> >
> > IDestination destination;
> >
> > IMessageConsumer messageConsumer;
> >
> >
> >
> > /*
> >
> > * the UI thread within whose context the code will be executed
> >
> > */
> >
> > private Form uiThread;
> >
> >
> > > /*
> >
> > * function in the UI thread to handle exceptions
> >
> > */
> >
> > private Delegate exceptionDelegate;
> >
> >
> > >
> > > public AMQMessageHandler(String connectionURI, String driverID,
> > > Delegate exceptionDelegate, Form uiThread)
> >
> > {
> >
> > this.connecturi = connectionURI;
> >
> > this.myQueue = "driver.channel." + driverID;
> >
> > this.uiThread = uiThread;
> >
> > this.exceptionDelegate = exceptionDelegate;
> >
> > }
> >
> >
> > > public void start()
> >
> > {
> >
> >
> > > try
> >
> > {
> >
> > this.factory = new ConnectionFactory(connecturi);
> >
> > this.connection = this.factory.CreateConnection();
> >
> > this.session = this.connection.CreateSession();
> >
> > this.destination = SessionUtil.GetDestination(session,
> > > "queue://" + myQueue);
> >
> > this.messageConsumer =
> session.CreateConsumer(destination);
> >
> >
> >
> > messageConsumer.Listener += new
> > > MessageListener(messageConsumer_Listener);
> >
> > connection.ExceptionListener += new
> > > ExceptionListener(connection_ExceptionListener);
> >
> > connection.Start();
> >
> >
> > > }
> >
> > catch (Exception ex)
> >
> > {
> >
> > uiThread.Invoke(exceptionDelegate,ex.Message);
> >
> > }
> >
> > }
> >
> >
> > > public delegate void RestartConnectionDelegate();
> >
> >
> > > private void restartConnection()
> >
> > {
> >
> > new System.Threading.Thread(threadedStartConnection).Start();
> >
> > }
> >
> >
> > > private void threadedStartConnection()
> >
> > {
> >
> > int retryCount = 1;
> >
> > bool keepTryingtoRestart = true;
> >
> >
> > > while (keepTryingtoRestart == true)
> >
> > {
> >
> > //tsalem - add some kind of logging here
> >
> > //listBox.Items.Add("attempting to reconnect - pass " +
> > > retryCount);
> >
> > System.Threading.Thread.Sleep(3000);
> >
> >
> > > try
> >
> > {
> >
> > this.factory = new ConnectionFactory(connecturi);
> >
> > this.connection = this.factory.CreateConnection();
> >
> > this.session = this.connection.CreateSession();
> >
> > this.destination =
> SessionUtil.GetDestination(session,
> > > "queue://" + myQueue);
> >
> > this.messageConsumer =
> > > session.CreateConsumer(destination);
> >
> > messageConsumer.Listener += new
> > > MessageListener(messageConsumer_Listener);
> >
> > connection.ExceptionListener += new
> > > ExceptionListener(connection_ExceptionListener);
> >
> > connection.Start();
> >
> >
> > > keepTryingtoRestart = false;
> >
> > }
> >
> > catch (Exception ex)
> >
> > {
> >
> > uiThread.Invoke(exceptionDelegate, ex.Message +"\n" +
> > > ex.StackTrace);
> >
> > //tsalem change this to check for keep retrying
> rather
> > > than on a counter
> >
> > if (retryCount == 50)
> >
> > {
> >
> > keepTryingtoRestart = false;
> >
> > }
> >
> >
> > > }
> >
> >
> >
> > retryCount++;
> >
> > }
> >
> > }
> >
> >
> > >
> > > public void messageConsumer_Listener(IMessage receivedMessage)
> >
> > {
> >
> > try
> >
> > {
> >
> > ITextMessage message = receivedMessage as ITextMessage;
> >
> > message.Acknowledge();
> >
> > //tsalem - todo - handle message
> >
> > if (message.Text != null)
> >
> > {
> >
> > AMQUtil.Instance.ResponseAvailable(message.Text,
> > > uiThread);
> >
> > }
> >
> > else
> >
> > {
> >
> > uiThread.Invoke(exceptionDelegate, "ERROR: AMQ
> Message
> > > is empty");
> >
> > }
> >
> > }
> >
> > catch (Exception ex)
> >
> > {
> >
> > uiThread.Invoke(exceptionDelegate,ex.Message);
> >
> > }
> >
> > }
> >
> >
> > >
> > >
> > > void connection_ExceptionListener(Exception exception)
> >
> > {
> >
> > uiThread.Invoke(exceptionDelegate,exception.Message);
> >
> >
> > > if (exception is System.IO.IOException)
> >
> > {
> >
> > //Invoke(new
> > > RestartConnectionDelegate(threadedStartConnection));
> >
> > threadedStartConnection();
> >
> > }
> >
> > }
> >
> > }
> >
> >
> > regards,
> > Tammer
>
> --
> Tim Bish
>
> Open Source Integration: http://fusesource.com
> ActiveMQ in Action: http://www.manning.com/snyder/
>
> Follow me on Twitter: http://twitter.com/tabish121
> My Blog: http://timbish.blogspot.com/
>
>
Re: NMS - cannot recover from connection failure
Posted by Timothy Bish <ta...@gmail.com>.
On Mon, 2010-05-10 at 15:04 +0100, Tammer Salem wrote:
> Hello All,
> I have an NMS client using the stomp broker on a .netcf device. For the most
> part it works absolutely fine, but now I'm trying to harden the device (for
> network failures etc.).
> I have added an exception listener and specifically look for IOExceptions
> (which I believe are what .NET throws if the GPRS/3G network connectivity
> dies). I can successfully capture this exception and then I fire off a
> thread to restart the connection and add my listeners again.
>
> At the moment this method doesn't seem to work - I can never get a
> connection again. Can anyone advise what is the best way of doing this?
>
So what happens exactly when the code attempts to create the new
Connection object and restore the Sessions and Destinations etc? Is
there an exception being thrown?
Regards
Tim.
> I've also attached my code so that you know what I'm trying to do.
>
> class AMQMessageHandler
>
> {
>
> private String myQueue;
>
> private String connecturi;
>
>
>
> //private ISession session;
>
> IConnectionFactory factory;
>
> IConnection connection;
>
> ISession session;
>
> IDestination destination;
>
> IMessageConsumer messageConsumer;
>
>
>
> /*
>
> * the UI thread within whose context the code will be executed
>
> */
>
> private Form uiThread;
>
>
> > /*
>
> * function in the UI thread to handle exceptions
>
> */
>
> private Delegate exceptionDelegate;
>
>
> >
> > public AMQMessageHandler(String connectionURI, String driverID,
> > Delegate exceptionDelegate, Form uiThread)
>
> {
>
> this.connecturi = connectionURI;
>
> this.myQueue = "driver.channel." + driverID;
>
> this.uiThread = uiThread;
>
> this.exceptionDelegate = exceptionDelegate;
>
> }
>
>
> > public void start()
>
> {
>
>
> > try
>
> {
>
> this.factory = new ConnectionFactory(connecturi);
>
> this.connection = this.factory.CreateConnection();
>
> this.session = this.connection.CreateSession();
>
> this.destination = SessionUtil.GetDestination(session,
> > "queue://" + myQueue);
>
> this.messageConsumer = session.CreateConsumer(destination);
>
>
>
> messageConsumer.Listener += new
> > MessageListener(messageConsumer_Listener);
>
> connection.ExceptionListener += new
> > ExceptionListener(connection_ExceptionListener);
>
> connection.Start();
>
>
> > }
>
> catch (Exception ex)
>
> {
>
> uiThread.Invoke(exceptionDelegate,ex.Message);
>
> }
>
> }
>
>
> > public delegate void RestartConnectionDelegate();
>
>
> > private void restartConnection()
>
> {
>
> new System.Threading.Thread(threadedStartConnection).Start();
>
> }
>
>
> > private void threadedStartConnection()
>
> {
>
> int retryCount = 1;
>
> bool keepTryingtoRestart = true;
>
>
> > while (keepTryingtoRestart == true)
>
> {
>
> //tsalem - add some kind of logging here
>
> //listBox.Items.Add("attempting to reconnect - pass " +
> > retryCount);
>
> System.Threading.Thread.Sleep(3000);
>
>
> > try
>
> {
>
> this.factory = new ConnectionFactory(connecturi);
>
> this.connection = this.factory.CreateConnection();
>
> this.session = this.connection.CreateSession();
>
> this.destination = SessionUtil.GetDestination(session,
> > "queue://" + myQueue);
>
> this.messageConsumer =
> > session.CreateConsumer(destination);
>
> messageConsumer.Listener += new
> > MessageListener(messageConsumer_Listener);
>
> connection.ExceptionListener += new
> > ExceptionListener(connection_ExceptionListener);
>
> connection.Start();
>
>
> > keepTryingtoRestart = false;
>
> }
>
> catch (Exception ex)
>
> {
>
> uiThread.Invoke(exceptionDelegate, ex.Message +"\n" +
> > ex.StackTrace);
>
> //tsalem change this to check for keep retrying rather
> > than on a counter
>
> if (retryCount == 50)
>
> {
>
> keepTryingtoRestart = false;
>
> }
>
>
> > }
>
>
>
> retryCount++;
>
> }
>
> }
>
>
> >
> > public void messageConsumer_Listener(IMessage receivedMessage)
>
> {
>
> try
>
> {
>
> ITextMessage message = receivedMessage as ITextMessage;
>
> message.Acknowledge();
>
> //tsalem - todo - handle message
>
> if (message.Text != null)
>
> {
>
> AMQUtil.Instance.ResponseAvailable(message.Text,
> > uiThread);
>
> }
>
> else
>
> {
>
> uiThread.Invoke(exceptionDelegate, "ERROR: AMQ Message
> > is empty");
>
> }
>
> }
>
> catch (Exception ex)
>
> {
>
> uiThread.Invoke(exceptionDelegate,ex.Message);
>
> }
>
> }
>
>
> >
> >
> > void connection_ExceptionListener(Exception exception)
>
> {
>
> uiThread.Invoke(exceptionDelegate,exception.Message);
>
>
> > if (exception is System.IO.IOException)
>
> {
>
> //Invoke(new
> > RestartConnectionDelegate(threadedStartConnection));
>
> threadedStartConnection();
>
> }
>
> }
>
> }
>
>
> regards,
> Tammer
--
Tim Bish
Open Source Integration: http://fusesource.com
ActiveMQ in Action: http://www.manning.com/snyder/
Follow me on Twitter: http://twitter.com/tabish121
My Blog: http://timbish.blogspot.com/