应用程序闲置一段时间后,Android套接字连接丢失

时间:2022-09-13 01:25:02

My application listens to a socket. The application is connected to the socket using the following method.

我的应用程序侦听套接字。应用程序使用以下方法连接到套接字。

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);


                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();
}

Here the problem is when I leave the application for 15 or more idle, the connection automatically closes and app becomes unusable.What is the reason behind it and how to resolve this?

这里的问题是当我离开应用程序15或更多空闲时,连接自动关闭,应用程序变得无法使用。它背后的原因是什么以及如何解决这个问题?

1 个解决方案

#1


Probably, it is the server that closes the idle connection. Send Ping (or Pong) periodically to keep the connection.

可能是关闭空闲连接的服务器。定期发送Ping(或Pong)以保持连接。

BTW, I guess your code is based on a certain open-source WebSocket library. If so, note that it is not of commercial quality. It does not perform even the closing handshake on disconnect().

顺便说一句,我猜您的代码基于某个开源WebSocket库。如果是这样,请注意它不具有商业品质。它甚至不执行disconnect()上的结束握手。

#1


Probably, it is the server that closes the idle connection. Send Ping (or Pong) periodically to keep the connection.

可能是关闭空闲连接的服务器。定期发送Ping(或Pong)以保持连接。

BTW, I guess your code is based on a certain open-source WebSocket library. If so, note that it is not of commercial quality. It does not perform even the closing handshake on disconnect().

顺便说一句,我猜您的代码基于某个开源WebSocket库。如果是这样,请注意它不具有商业品质。它甚至不执行disconnect()上的结束握手。