Reputation: 8790
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
Upvotes: 7
Views: 17042
Reputation: 22051
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.
Upvotes: 5
Reputation: 31008
Here's how I would start troubleshooting this:
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.
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.
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).
Upvotes: 5