感谢阅读!
背景:
我正在为服务器开发一个 Android 客户端,其中要求应用程序需要与基于 WebSockets
的服务器来回连续交换消息。
实现:对于客户端,我使用weberknecht's Android 的 WebSocket
客户端库,而服务器是基于 Tornado
的。
问题:
目前,我通过生成 AsyncTask
在 onCreate
中调用 initWebSocketClient
。但是,我不断收到客户端超时异常。
安卓客户端:
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 服务器:
#!/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()
客户端超时异常:
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
有人可以帮帮我吗?
更新:添加 AutoBahn(适用于 Android 的 WebSocket 客户端库)实现细节:
高速公路客户端
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());
}
}
有了这个库——我可以连接到服务器,但连接立即断开。 (请参阅下面的“AutoBahn 客户端日志”。切换回 weberknecht 工作正常。我没有在任何地方明确调用 mConnection.disconnect()
。所以我不知道连接是如何终止的。
AutoBahn 客户端日志
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
最佳答案
以下是我开始解决此问题的方法:
您是尝试在手机(设备)还是模拟器上执行此操作?如果您尝试在您的手机上执行此操作,您是通过 3G 连接的,则不会发生这种情况。在这种情况下,您正尝试从不起作用的 WAN 连接到一个内部 IP 地址。
再次假设您是在设备上执行此操作,如果您是通过 Wifi 连接的,那就是另一回事了。确保服务器可以到达
192.168.207.84:8080
。一种快速测试连接性的方法(从您的 PC):telnet 192.168.207.84 8080
如果超时,您就知道您的服务器没有响应。这当然假设您的 PC 与您的 Wifi 网络位于同一子网。
如果您尝试从您的模拟器执行此操作,请按照 [2] 中的步骤确保服务器可访问,并确保您的模拟器处于 (IP) 桥接模式。
总而言之,超时的主要原因通常是因为服务器可用性不足(即缺乏连接)。您没有提到您的网络的详细信息,所以我在这里根据您尝试连接的 IP (192.168.207.84) 做了一些假设。
关于android websocket客户端超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9089231/