8

My android app is connected to the server through socket, which is coded in node.js. When the is left in the foreground for 15 minutes it losses connection to the server. The following is the code that connects the sockt to the server

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

anu solution to this problem?

2 Answers 2

7

After googling a lot I found out a solution to this problem. Add timeout to the socket connection.

mSocket.setSoTimeout(10*1000);

If there isn't any response, after 10 seconds it will throw SocketTimeoutException and in the catch of this exception close the connection if exists, then connect again.

catch (SocketTimeoutException e) {
  if (mSocket.isConnected()) {
    disconnect();
  }
  connect();
}
Sign up to request clarification or add additional context in comments.

Comments

7

This is a simple example that shows how to set the timeout on a java socket :

sockAdr = new InetSocketAddress(SERVER_HOSTNAME, SERVER_PORT);
socket = new Socket();
timeout = 5000; // 5 seconds
socket.connect(sockAdr, timeout);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream());
while ((data = reader.readLine())!=null) 
      log.e(TAG, "received -> " + data);
log.e(TAG, "Socket closed !");

1 Comment

This is the correct answer, because setting the timeout after as in the accepted answer will have no effect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.