Android套接字连接超时

标签 android sockets timeout

我的android应用程序通过套接字连接到服务器,套接字是在node.js中编码的。当 留在前台 15 分钟时,它会失去与服务器的连接。下面是sockt连接到服务器的代码

public void connect() {
    this.connectionStatus = CONNECT_STATUS_CONNECTING;
    Log.v(AppConstants.DEBUG_TAG, userId + " : Connecting to Server");
    if (mThread != null && mThread.isAlive()) {
        return;
    }
    mThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Log.v(AppConstants.DEBUG_TAG, userId + " : Thread Action Started");
                String secret = createSecret();

                int port = (mURI.getPort() != -1) ? mURI.getPort() : (mURI.getScheme().equals("wss") ? 443 : 80);

                String path = TextUtils.isEmpty(mURI.getPath()) ? "/" : mURI.getPath();
                if (!TextUtils.isEmpty(mURI.getQuery())) {
                    path += "?" + mURI.getQuery();
                }
                String originScheme = mURI.getScheme().equals("wss") ? "https" : "http";
                URI origin = new URI(originScheme, "//" + mURI.getHost(), null);

                SocketFactory factory = mURI.getScheme().equals("wss") ? getSSLSocketFactory() : SocketFactory.getDefault();
                mSocket = factory.createSocket(mURI.getHost(), port);
                mSocket.setKeepAlive(true);


                PrintWriter out = new PrintWriter(mSocket.getOutputStream());
                out.print("GET " + path + " HTTP/1.1\r\n");
                out.print("Upgrade: websocket\r\n");
                out.print("Connection: Upgrade\r\n");
                out.print("Host: " + mURI.getHost() + "\r\n");
                out.print("Origin: " + origin.toString() + "\r\n");
                out.print("Sec-WebSocket-Key: " + secret + "\r\n");
                out.print("Sec-WebSocket-Version: 13\r\n");
                if (mExtraHeaders != null) {
                    for (NameValuePair pair : mExtraHeaders) {
                        out.print(String.format("%s: %s\r\n", pair.getName(), pair.getValue()));
                    }
                }
                out.print("\r\n");
                out.flush();

                HybiParser.HappyDataInputStream stream = new HybiParser.HappyDataInputStream(mSocket.getInputStream());

                // Read HTTP response status line.
                StatusLine statusLine = parseStatusLine(readLine(stream));
                if (statusLine == null) {
                    Log.v(AppConstants.DEBUG_TAG, "Received no reply from server.");
                    throw new HttpException("Received no reply from server.");
                } else if (statusLine.getStatusCode() != HttpStatus.SC_SWITCHING_PROTOCOLS) {
                    throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
                }

                // Read HTTP response headers.
                String line;
                boolean validated = false;

                while (!TextUtils.isEmpty(line = readLine(stream))) {
                    Header header = parseHeader(line);
                    if (header.getName().equals("Sec-WebSocket-Accept")) {
                        String expected = createSecretValidation(secret);
                        String actual = header.getValue().trim();

                        if (!expected.equals(actual)) {
                            Log.v(AppConstants.DEBUG_TAG, "Bad Sec-WebSocket-Accept header value.");
                            throw new HttpException("Bad Sec-WebSocket-Accept header value.");
                        }
                        validated = true;
                    }
                }

                if (!validated) {
                    Log.v(AppConstants.DEBUG_TAG, "No Sec-WebSocket-Accept header.");
                    throw new HttpException("No Sec-WebSocket-Accept header.");
                }
                onConnect();
                Log.v(AppConstants.DEBUG_TAG, userId + " : Thread should be connected by now");
                // Now decode websocket frames.
                mParser.start(stream);
            } catch (EOFException ex) {
                Log.d(AppConstants.DEBUG_TAG, "WebSocket EOF!", ex);
                onDisconnect(0, "EOF");
            } catch (SSLException ex) {
                // Connection reset by peer
                Log.d(AppConstants.DEBUG_TAG, "Websocket SSL error!", ex);
                onDisconnect(0, "SSL");
            } catch (Exception ex) {
                onError(ex);
            }
        }
    });
    Log.v(AppConstants.DEBUG_TAG, userId + " : Thread about to be started");
    mThread.start();
}

这个问题的解决方案?

最佳答案

经过大量谷歌搜索后,我找到了解决此问题的方法。为套接字连接添加超时。

mSocket.setSoTimeout(10*1000);

如果没有任何响应,10 秒后它将抛出 SocketTimeoutException 并在捕获此异常时关闭连接(如果存在),然后重新连接。

catch (SocketTimeoutException e) {
  if (mSocket.isConnected()) {
    disconnect();
  }
  connect();
}

关于Android套接字连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30378288/

相关文章:

android - 如何在Android中添加HttpClient请求和连接超时

android - Gradle 中的 Android 库可以将其他 Android 库作为依赖项吗?

java - 关于 RadioGroup 处理的困惑

c - Winsock 错误 1013 - 权限被拒绝

javascript - 搜索栏以在 React 中过滤表结果并超时

sql-server - LINQ:DataContext Life 和 System.Data.SqlClient.SqlException:超时已过期

android - 带有自定义 FirebaseOptions 初始化方法的 Firebase Google Analytics

java - 如何在android中实现客户端服务器来制作BINGO游戏,但不用于聊天应用程序

sockets - Rust并发读写导致的死锁问题?

java - 套接字异常 : Connection reset after reconnect