android websocket client timeout
Asked Answered
J

2

7

Thanks for reading!

Background: I am developing an Android client for a server where the requirement is app that requires continuous exchange of messages back and forth with a WebSockets-based server.

Implementation: For the client, I use weberknecht's WebSocket client library for Android while the server is Tornado-based.

Problem: For the moment, I invoke initWebSocketClient in onCreate by spawning an AsyncTask. But, I keep getting a client timeout exception.

Android Client:


private void initWebSocketClient() {
        Log.e(TAG, "initWebSocketClient");
        try {
            URI url = new URI("ws://192.168.207.84:8080/");
            WebSocket websocket = new WebSocketConnection(url);

            // Register Event Handlers
            websocket.setEventHandler(new WebSocketEventHandler() {
                    public void onOpen()
                    {
                            Log.e(TAG, "--open");
                    }

                    public void onMessage(WebSocketMessage message)
                    {
                            Log.e(TAG, "--received message: " + message.getText());
                    }

                    public void onClose()
                    {
                            Log.e(TAG, "--close"); 
                    }
            });

            // Establish WebSocket Connection
            websocket.connect();

            // Send UTF-8 Text
            websocket.send("hello world");

            // Close WebSocket Connection
            websocket.close();
        }
        catch (WebSocketException wse) {
                wse.printStackTrace();
        }
        catch (URISyntaxException use) {
                use.printStackTrace();
        }
    }

Tornado Server:


#!/usr/bin/env python

import tornado.ioloop
import tornado.web
import tornado.websocket

class EchoWebSocketHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print "WebSocket opened"

    def on_message(self, message):
        self.write_message(u"You said: " + message)

    def on_close(self):
        print "WebSocket closed"

application = tornado.web.Application([
    (r"/", EchoWebSocketHandler),
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()

Client Timeout exception:


01-31 19:28:01.367: W/System.err(5668): de.roderick.weberknecht.WebSocketException: error while creating socket to ws://192.168.207.84:8080/
01-31 19:28:01.386: W/System.err(5668):     at de.roderick.weberknecht.WebSocketConnection.createSocket(WebSocketConnection.java:244)
01-31 19:28:01.386: W/System.err(5668):     at de.roderick.weberknecht.WebSocketConnection.connect(WebSocketConnection.java:83)
01-31 19:28:01.386: W/System.err(5668):     at com.sagar.websockclient.MainActivity.initWebSocketClient(MainActivity.java:55)
01-31 19:28:01.390: W/System.err(5668):     at com.sagar.websockclient.MainActivity.access$0(MainActivity.java:30)
01-31 19:28:01.390: W/System.err(5668):     at com.sagar.websockclient.MainActivity$WebSocketTask.doInBackground(MainActivity.java:75)
01-31 19:28:01.390: W/System.err(5668):     at com.sagar.websockclient.MainActivity$WebSocketTask.doInBackground(MainActivity.java:1)
01-31 19:28:01.390: W/System.err(5668):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
01-31 19:28:01.390: W/System.err(5668):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-31 19:28:01.390: W/System.err(5668):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-31 19:28:01.390: W/System.err(5668):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-31 19:28:01.390: W/System.err(5668):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-31 19:28:01.390: W/System.err(5668):     at java.lang.Thread.run(Thread.java:856)
01-31 19:28:01.390: W/System.err(5668): Caused by: java.net.ConnectException: failed to connect to /192.168.207.84 (port 8080): connect failed: ETIMEDOUT (Connection timed out)
01-31 19:28:01.390: W/System.err(5668):     at libcore.io.IoBridge.connect(IoBridge.java:114)
01-31 19:28:01.394: W/System.err(5668):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
01-31 19:28:01.394: W/System.err(5668):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
01-31 19:28:01.394: W/System.err(5668):     at java.net.Socket.startupSocket(Socket.java:566)
01-31 19:28:01.394: W/System.err(5668):     at java.net.Socket.tryAllAddresses(Socket.java:127)
01-31 19:28:01.394: W/System.err(5668):     at java.net.Socket.(Socket.java:177)
01-31 19:28:01.394: W/System.err(5668):     at java.net.Socket.(Socket.java:149)
01-31 19:28:01.394: W/System.err(5668):     at de.roderick.weberknecht.WebSocketConnection.createSocket(WebSocketConnection.java:238)
01-31 19:28:01.394: W/System.err(5668):     ... 11 more
01-31 19:28:01.394: W/System.err(5668): Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
01-31 19:28:01.398: W/System.err(5668):     at libcore.io.Posix.connect(Native Method)
01-31 19:28:01.398: W/System.err(5668):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
01-31 19:28:01.398: W/System.err(5668):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
01-31 19:28:01.398: W/System.err(5668):     at libcore.io.IoBridge.connect(IoBridge.java:112)
01-31 19:28:01.398: W/System.err(5668):     ... 18 more

Could someone please help me out here?

Update: Adding AutoBahn (WebSocket client library for Android) implementation details:

AutoBahn Client


private void connect2() {
        mConnection = new WebSocketConnection();
        final String wsuri = "ws://192.168.0.137:8888/";
        String TAG = "ArticlesListActivity"; 

        try {
            mConnection.connect(wsuri, new WebSocketHandler() {
               @Override
               public void onOpen() {
                 Log.e(TAG, "Connected to: " + wsuri);
               }

               @Override
               public void onTextMessage(String payload) {
                  Log.e(TAG, "Message recieved = " + payload);
               }

               @Override
               public void onClose(int code, String reason) {
                  Log.e(TAG, "Connection Lost.");
               }
            });
         } catch (WebSocketException e) {

            Log.d(TAG, e.toString());
         }      
    }

With this library - I am able to connect to the server but instantly, the connection is lost. (Refer the "AutoBahn Client Log" below. Switching back to weberknecht works just fine. I am NOT explicitly calling mConnection.disconnect() anywhere. So I don't know how the connection gets terminated.

AutoBahn Client Log


02-27 14:27:36.605: D/de.tavendo.autobahn.WebSocketConnection(27701): created
02-27 14:27:36.656: D/dalvikvm(27701): GC_FOR_ALLOC freed 164K, 4% free 9247K/9543K, paused 17ms
02-27 14:27:36.671: D/dalvikvm(27701): GC_FOR_ALLOC freed 7K, 4% free 9368K/9735K, paused 14ms
02-27 14:27:36.671: D/de.tavendo.autobahn.WebSocketReader(27701): created
02-27 14:27:36.675: D/de.tavendo.autobahn.WebSocketConnection(27701): WS reader created and started
02-27 14:27:36.675: D/de.tavendo.autobahn.WebSocketReader(27701): running
02-27 14:27:36.675: D/de.tavendo.autobahn.WebSocketWriter(27701): created
02-27 14:27:36.675: D/de.tavendo.autobahn.WebSocketConnection(27701): WS writer created and started
02-27 14:27:36.769: D/de.tavendo.autobahn.WebSocketReader(27701): run() : ConnectionLost
02-27 14:27:36.773: D/de.tavendo.autobahn.WebSocketReader(27701): ended
02-27 14:27:36.777: D/de.tavendo.autobahn.WebSocketConnection(27701): opening handshake received
02-27 14:27:36.777: E/ArticlesListActivity(27701): Connected to: ws://192.168.0.137:8888/
02-27 14:27:36.781: D/de.tavendo.autobahn.WebSocketConnection(27701): fail connection [code = 3, reason = WebSockets connection lost
02-27 14:27:36.784: D/de.tavendo.autobahn.WebSocketReader(27701): quit
02-27 14:27:36.788: D/de.tavendo.autobahn.WebSocketWriter(27701): ended
02-27 14:27:36.792: E/ArticlesListActivity(27701): Connection Lost.
02-27 14:27:36.792: D/de.tavendo.autobahn.WebSocketConnection(27701): worker threads stopped
Janenejanenna answered 1/2, 2012 at 0:43 Comment(0)
P
5

Here's how I would start troubleshooting this:

  1. Are you attempting to do this on your phone (device) or the emulator? If you're attempting to do this on your phone and you're connected via 3G, it is not going to happen. In this scenario, you're attempting to connect to an internal IP address from the WAN which doesn't work.

  2. Again assuming you're doing this on a device, if you're connected via Wifi then it's another story. Make sure the server can be reached at 192.168.207.84:8080. A quick way to test connectivity (from your PC):

    telnet 192.168.207.84 8080
    

    If it times out, you know your server isn't responding. This of course assumes your PC is on the same subnet as your Wifi network.

  3. If you're attempting to do this from your emulator, follow the steps in [2] to make sure the server is reachable and also ensure your emulator is in (IP) bridged mode.

To summarize, the main reason timeouts usually occur is because of lack of server availability (i.e. lack of connectivity). You didn't mention the details of your network so I made a few assumptions here based on the IP you were trying to connect to (192.168.207.84).

Pucka answered 1/2, 2012 at 22:9 Comment(1)
Awesome! Thanks @Marvin for the detailed explanation, that totally helped me solve the problem. I was using a device but my server was on an internal IP. So, now I logged both the server and the device on the same wifi and was able to get it to connect the server!Janenejanenna
M
5

As far as I can see, Weberknecht does only support Hybi-10, not the final RFC6455 spec, and more problematic, does it's networking on the main (UI) thread. That is generally a bad idea, and will fail on Android >2.

For Android native apps, there is Autobahn WebSockets for Android

https://github.com/oberstet/AutobahnAndroid

It supports the final RFC6455, integrates well with UI and service apps, provides RPC and PubSub over WebSockets, and more. Check out the project README on GitHub.

Disclaimer: I am the author of Autobahn.

Mcclenaghan answered 14/2, 2012 at 9:48 Comment(15)
Thanks for the info! Your solution sounds full-fledged and I had looked at back when I was researching but I didn't see a WebSockets for Android here: tavendo.de/autobahn/tutorials.html BTW, just wondering if it's free for commercial use?Janenejanenna
BTW, I spawn an AsyncTask for the websockets network activity so, it works fine for now.Janenejanenna
Code is under Apache 2.0 license .. open-source. Rgd. AsyncTask .. with the latest code you dont need that, since not only the socket read/write are done on background threads, but also the initial socket connect. That latter point was different until just recently .. did read/write on background thread, but not the initial socket connect .. whcih causes "network on UI" thread issues on recent Android.Mcclenaghan
I see, thanks for the details. Does it support Tornado Websockets 2.2? Because, just today I figured that weberkneckt supports a max of 2.1.Janenejanenna
Autobahn for Android supports WebSockets protocol draft version Hybi-10 up to teh final RFC6455. I don't known what Tornado WS 2.2 implements ..Mcclenaghan
I tried the AutoBahn "Broadcast Client" library. See "Update" above. But I fail to connect to the server. Could you help me out?Janenejanenna
I've added more debug log output -- could you fetch the latest github.com/oberstet/AutobahnAndroid rebuild, rerun, and reattach the adb logcat output? Hopefully that will shed some light upon the issue.Mcclenaghan
Actually, I just misunderstood the problem. Turns out, actually the connection is established with the server ( I am Logging "ActiclesListActivity: Connected to ws://192.168.0.137:8888/ in the onOpen method" and then for some reason, the connection is lost.Janenejanenna
It seems the server is dropping the TCP connection after replying to handshake .. I see if I can get Tornado 2.2 (that's what you are using, right?) running .. and that includes already a WS server implementation? Also, could you pastebin your server code (something stripped down is sufficient), so I can test?Mcclenaghan
It's a test webserver and all the server code is as above under "Tornado Server". I am on 2.1.1. Should I upgrade?Janenejanenna
Works for me: Tornado 2.2 + your code above + Echo client demo from Autobahn Android. Probably Tornado 2.1 WS impl. might be too old .. try 2.2 ..Mcclenaghan
Gotcha. I just upgraded to 2.2 and it worked! Awesome! Thanks!! I have decided to use your library as it's much more active and supports the final RFC 6455 protocol. Thansk for all the support!Janenejanenna
excellent;) should you run into issues again, don't hesitate to contact again .. probably best on the mailing list groups.google.com/group/autobahnws which I monitor more closely ..Mcclenaghan
Sure, thanks! That helps. I am now testing this client with a simple SocketIO webserver. Is this supported? You can respond in your forum.Janenejanenna
Thanks for the explaination ... I faced similar issue and yes the client I use supports Hypi only HybiParser.javaLade

© 2022 - 2024 — McMap. All rights reserved.