Autobahn Android : How to disconnect to the server

#1

Hi ! I posted in stackoverflow a problem I have with Autobahn Android

http://stackoverflow.com/questions/17315624/autobahn-android-how-to-disconnect-to-the-server?noredirect=1#comment25114499_17315624

Maybe you can help me ! Here is the content:

I’m using Jetty WebSockets for the server side and Autobahn Android for the client one.

A simple connection between server and client works fine. But I’m having some trouble when I try to handle the loss of connection.

On Android, what I have is this:

private void connectToServer() {

        try {

            mConnection.connect(getString(R.string.server_addr), new WebSocketHandler(){

                // connection au serveur
                @Override
                public void onOpen(){
                    Log.d(TAG, "Connected");
                    Log.d(TAG, "First connexion, sending MAC @");
                    Log.d(TAG, "My MAC Addr: "+ macAddr);
                    mConnection.sendTextMessage(macAddr);

                }
                // reception d'un message text
                @Override
                 public void onTextMessage(String payload) {

                    //TODO
                 }

                // fermeture de la connexion
                 @Override
                 public void onClose(int code, String reason) {
                    Log.d(TAG, "Connection lost. "+reason);
                    if(mConnection.isConnected()){
                        Log.d(TAG, "Still connected, disconnect!");
                        mConnection.disconnect();
                    }
                    if(code<4000){
                        int totalWaitTime = 0;
                        int waitTime = 0;
                        Log.d(TAG, "Should be disconnected");
                        while(!mConnection.isConnected()){
                            try {
                                waitTime= random.nextInt(MAX_TO_WAIT - MIN_TO_WAIT + 1) + MIN_TO_WAIT;
                                Log.d(TAG, "I'll wait "+waitTime+"ms");
                                totalWaitTime +=waitTime;
                                Log.d(TAG, "Waiting for "+totalWaitTime+"ms");
                                if(totalWaitTime <= HOUR_TO_MS){
                                    Thread.sleep(waitTime);
                                    Log.d(TAG, "Trying to reconnect");
                                    connectToServer();
                                }else{
                                    throw new InterruptedException("Attempt to connect to the server during 1 hours without success");
                                }
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                 }
            });
        } catch (WebSocketException e) {

            Log.e(TAG, "Error on connect: "+e.toString());
            Log.d(TAG, "is connected: "+mConnection.isConnected());
            if(mConnection.isConnected())
                mConnection.disconnect();
            connectToServer();
        }

    }

And I always, always have the same error:

06-26 10:36:07.823: E/wingo.stb.qos.AutoStartService(1842): Error on connect: de.tavendo.autobahn.WebSocketException: already connected

But like you can see, I close the connection in onClose(), and when a WebSocketException is catched. Does this method really works ? Or am I doing it wrong ?

By the way, mConnection is final. So maybe the problem comes here ?

private final WebSocketConnection mConnection = new WebSocketConnection();

On the server, when I have a connection loss I manually close the session:

@OnWebSocketClose
    public void onClose(Session session, int closeCode, String closeReason){
            try {
                System.out.println("connexion closed. Reason: "+closeReason);
                pingPongTimer.cancel();
                if(session.isOpen())
                    session.close();
                WebSocketsCentralisation.getInstance().leave(this);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

Thanks in advance awesome people!

0 Likes

#2

Jetty developer here …

Do not issue a session.close() within the onClose() on the server side.

That’s just a bad idea.

You got notified on the close handshake, and the jetty implementation will respond automatically on the close handshake (then once it the handshake is satisfied, the connection is disconnected)

However, in your example you got notified, and then you attempted to start another close handshake, where jetty is already in the role of managing that close handshake.

Another thing that confuses people is that per the WebSocket spec, a socket can enter into a half-closed state where it has stated its desire to close (initiating the handshake), essentially saying it will no longer write data, but it can still read frames until it receives a close from the other side. Unfortunately, the expectations that “close” means “disconnect” isn’t present in WebSocket. It has a state where it goes from OPEN -> CLOSING -> CLOSED -> DISCONNECTED. This being said, if you prefer to have a harsh disconnect of the low level connection, and not wait for the close handshake, you could use the Session.disconnect() from the Jetty WebSocket API.

Also note, that there were a few server close/disconnect bugs in Jetty 9.0.3 (and earlier).

These have been addressed in Jetty 9.0.4.v20130625 (incidentally released yesterday).

Interestingly, the autobahn side error “already connected” seems to indicate another part of the spec that is often not understood. (Section 4.1 Client Requirements) where there are limits on the number of simultaneous connections to an endpoint (the limits are recommendations based on context)

···

On Wed, Jun 26, 2013 at 2:07 AM, Alan Brunetti alan.b...@gmail.com wrote:

Hi ! I posted in stackoverflow a problem I have with Autobahn Android

http://stackoverflow.com/questions/17315624/autobahn-android-how-to-disconnect-to-the-server?noredirect=1#comment25114499_17315624

Maybe you can help me ! Here is the content:

I’m using Jetty WebSockets for the server side and Autobahn Android for the client one.

A simple connection between server and client works fine. But I’m having some trouble when I try to handle the loss of connection.

On Android, what I have is this:

private void connectToServer() {

        try {

            mConnection.connect(getString(R.string.server_addr), new WebSocketHandler(){

                // connection au serveur
                @Override
                public void onOpen(){
                    Log.d(TAG, "Connected");
                    Log.d(TAG, "First connexion, sending MAC @");
                    Log.d(TAG, "My MAC Addr: "+ macAddr);
                    mConnection.sendTextMessage(macAddr);

                }
                // reception d'un message text
                @Override
                 public void onTextMessage(String payload) {

                    //TODO
                 }

                // fermeture de la connexion
                 @Override
                 public void onClose(int code, String reason) {
                    Log.d(TAG, "Connection lost. "+reason);
                    if(mConnection.isConnected()){
                        Log.d(TAG, "Still connected, disconnect!");
                        mConnection.disconnect();
                    }
                    if(code<4000){
                        int totalWaitTime = 0;
                        int waitTime = 0;
                        Log.d(TAG, "Should be disconnected");
                        while(!mConnection.isConnected()){
                            try {
                                waitTime= random.nextInt(MAX_TO_WAIT - MIN_TO_WAIT + 1) + MIN_TO_WAIT;
                                Log.d(TAG, "I'll wait "+waitTime+"ms");
                                totalWaitTime +=waitTime;
                                Log.d(TAG, "Waiting for "+totalWaitTime+"ms");
                                if(totalWaitTime <= HOUR_TO_MS){
                                    Thread.sleep(waitTime);
                                    Log.d(TAG, "Trying to reconnect");
                                    connectToServer();
                                }else{
                                    throw new InterruptedException("Attempt to connect to the server during 1 hours without success");
                                }
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                 }
            });
        } catch (WebSocketException e) {

            Log.e(TAG, "Error on connect: "+e.toString());
            Log.d(TAG, "is connected: "+mConnection.isConnected());
            if(mConnection.isConnected())
                mConnection.disconnect();
            connectToServer();
        }

    }

And I always, always have the same error:

06-26 10:36:07.823: E/wingo.stb.qos.AutoStartService(1842): Error on connect: de.tavendo.autobahn.WebSocketException: already connected

But like you can see, I close the connection in onClose(), and when a WebSocketException is catched. Does this method really works ? Or am I doing it wrong ?

By the way, mConnection is final. So maybe the problem comes here ?

private final WebSocketConnection mConnection = new WebSocketConnection();

On the server, when I have a connection loss I manually close the session:

@OnWebSocketClose
    public void onClose(Session session, int closeCode, String closeReason){
            try {
                System.out.println("connexion closed. Reason: "+closeReason);
                pingPongTimer.cancel();
                if(session.isOpen())
                    session.close();
                WebSocketsCentralisation.getInstance().leave(this);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

Thanks in advance awesome people!

You received this message because you are subscribed to the Google Groups “Autobahn” group.

To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

0 Likes

#3

Thank you for those information!

So on Jetty I’m doing a loop ? onClose, close, onClose, close … ?

Do you think I’m doing the same thing on Android with Autobahn ?

···

On Wednesday, June 26, 2013 2:48:39 PM UTC+2, Joakim Erdfelt wrote:

Jetty developer here …

Do not issue a session.close() within the onClose() on the server side.

That’s just a bad idea.

You got notified on the close handshake, and the jetty implementation will respond automatically on the close handshake (then once it the handshake is satisfied, the connection is disconnected)

However, in your example you got notified, and then you attempted to start another close handshake, where jetty is already in the role of managing that close handshake.

Another thing that confuses people is that per the WebSocket spec, a socket can enter into a half-closed state where it has stated its desire to close (initiating the handshake), essentially saying it will no longer write data, but it can still read frames until it receives a close from the other side. Unfortunately, the expectations that “close” means “disconnect” isn’t present in WebSocket. It has a state where it goes from OPEN -> CLOSING -> CLOSED -> DISCONNECTED. This being said, if you prefer to have a harsh disconnect of the low level connection, and not wait for the close handshake, you could use the Session.disconnect() from the Jetty WebSocket API.

Also note, that there were a few server close/disconnect bugs in Jetty 9.0.3 (and earlier).

These have been addressed in Jetty 9.0.4.v20130625 (incidentally released yesterday).

Interestingly, the autobahn side error “already connected” seems to indicate another part of the spec that is often not understood. (Section 4.1 Client Requirements) where there are limits on the number of simultaneous connections to an endpoint (the limits are recommendations based on context)

On Wed, Jun 26, 2013 at 2:07 AM, Alan Brunetti alan...@gmail.com wrote:

Hi ! I posted in stackoverflow a problem I have with Autobahn Android

http://stackoverflow.com/questions/17315624/autobahn-android-how-to-disconnect-to-the-server?noredirect=1#comment25114499_17315624

Maybe you can help me ! Here is the content:

I’m using Jetty WebSockets for the server side and Autobahn Android for the client one.

A simple connection between server and client works fine. But I’m having some trouble when I try to handle the loss of connection.

On Android, what I have is this:

private void connectToServer() {

        try {

            mConnection.connect(getString(R.string.server_addr), new WebSocketHandler(){

                // connection au serveur
                @Override
                public void onOpen(){
                    Log.d(TAG, "Connected");
                    Log.d(TAG, "First connexion, sending MAC @");
                    Log.d(TAG, "My MAC Addr: "+ macAddr);
                    mConnection.sendTextMessage(macAddr);

                }
                // reception d'un message text
                @Override
                 public void onTextMessage(String payload) {

                    //TODO
                 }

                // fermeture de la connexion
                 @Override
                 public void onClose(int code, String reason) {
                    Log.d(TAG, "Connection lost. "+reason);
                    if(mConnection.isConnected()){
                        Log.d(TAG, "Still connected, disconnect!");
                        mConnection.disconnect();
                    }
                    if(code<4000){
                        int totalWaitTime = 0;
                        int waitTime = 0;
                        Log.d(TAG, "Should be disconnected");
                        while(!mConnection.isConnected()){
                            try {
                                waitTime= random.nextInt(MAX_TO_WAIT - MIN_TO_WAIT + 1) + MIN_TO_WAIT;
                                Log.d(TAG, "I'll wait "+waitTime+"ms");
                                totalWaitTime +=waitTime;
                                Log.d(TAG, "Waiting for "+totalWaitTime+"ms");
                                if(totalWaitTime <= HOUR_TO_MS){
                                    Thread.sleep(waitTime);
                                    Log.d(TAG, "Trying to reconnect");
                                    connectToServer();
                                }else{
                                    throw new InterruptedException("Attempt to connect to the server during 1 hours without success");
                                }
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                 }
            });
        } catch (WebSocketException e) {

            Log.e(TAG, "Error on connect: "+e.toString());
            Log.d(TAG, "is connected: "+mConnection.isConnected());
            if(mConnection.isConnected())
                mConnection.disconnect();
            connectToServer();
        }

    }

And I always, always have the same error:

06-26 10:36:07.823: E/wingo.stb.qos.AutoStartService(1842): Error on connect: de.tavendo.autobahn.WebSocketException: already connected

But like you can see, I close the connection in onClose(), and when a WebSocketException is catched. Does this method really works ? Or am I doing it wrong ?

By the way, mConnection is final. So maybe the problem comes here ?

private final WebSocketConnection mConnection = new WebSocketConnection();

On the server, when I have a connection loss I manually close the session:

@OnWebSocketClose
    public void onClose(Session session, int closeCode, String closeReason){
            try {
                System.out.println("connexion closed. Reason: "+closeReason);
                pingPongTimer.cancel();
                if(session.isOpen())
                    session.close();
                WebSocketsCentralisation.getInstance().leave(this);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

Thanks in advance awesome people!

You received this message because you are subscribed to the Google Groups “Autobahn” group.

To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

0 Likes

#4

But well, to simulate the fact that the server is down I stop it. So the problem doesn’t come from the server. I’m a little bit stuck.

It’s maybe because mConnection is final… Maybe I should have a new instance of my Service.

0 Likes