Keep connection open and read data till it is forc

2019-07-08 06:52发布

问题:

When my activity loads, I am connecting to a web service. As and when I get the response from service, I again call then service and so on.

@Override
protected void onCreate(Bundle savedInstanceState) {  
….  
callWebMethod();
}  

// Called on getting response  
@Override
public void run(String value) {  
….  
callWebMethod();  
}  

This is how I am connecting to service

HttpGet request = new HttpGet(url + combinedParams);  
HttpClient client = new DefaultHttpClient(httpParameters);

    HttpResponse httpResponse;

        httpResponse = client.execute(request);
        responseCode = httpResponse.getStatusLine().getStatusCode();
        message = httpResponse.getStatusLine().getReasonPhrase();

        HttpEntity entity = httpResponse.getEntity();

        if (entity != null) {

            InputStream instream = entity.getContent();
            response = convertStreamToString(instream);
            response = StringUtils.remove(response, "\n");
            response = StringUtils.remove(response, '"');
        }  

Is it possible that I connect to the service only once at the start, then the connection remains open and application keeps on reading data from service till connection is forcefully closed.
Please let me know if more code is required.

Update: I then tried with ClientConnectionManager but still connection is again and again initialising. Though it is getting data. What I want is that connection remains open, and keeps on reading data from service.

HttpParams httpParameters = new BasicHttpParams();

    SharedPreferences preferences = context.getSharedPreferences(
            "MyPreferences", Context.MODE_PRIVATE);

    int timeoutConnection = Integer.parseInt(preferences.getString(
            "timeout", "60")) * 1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters,
            timeoutConnection);

    HttpConnectionParams.setSoTimeout(httpParameters, 2000);
    System.setProperty("http.keepAlive", "true");
    HttpClient client = new DefaultHttpClient(httpParameters);

    ClientConnectionManager mgr = client.getConnectionManager();
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(
            client.getParams(), mgr.getSchemeRegistry()),
            client.getParams());
    while (true) {

        HttpResponse httpResponse;

        try {
            httpResponse = client.execute(request);
            responseCode = httpResponse.getStatusLine().getStatusCode();
            message = httpResponse.getStatusLine().getReasonPhrase();

            HttpEntity entity = httpResponse.getEntity();

            if (entity != null) {

                InputStream instream = entity.getContent();
                response = convertStreamToString(instream);
                response = StringUtils.remove(response, "\n");
                response = StringUtils.remove(response, '"');
                ((Activity) context).runOnUiThread(new Runnable() {
                    public void run() {
                        callback.run(response);  // This calls activity callback function.
                    }
                });

                // Closing the input stream will trigger connection release
                // instream.close();
            }

        } catch (ConnectTimeoutException e) {
         ….  
         }

回答1:

It sounds like what you really need is a socket connection (see here). A socket will stay connected and allow you to stream data back and forth with the socket server until you are finished.



回答2:

you just need to close the InputStream you get from HttpResponse.getEntity().getContent() after you are done using/reading-it. This will officially indicate the end of your current request.

You can then proceed to execute another request, the same HttpClient connection will be used.

Add a close

        InputStream instream = entity.getContent();
        response = convertStreamToString(instream); 
        // close the InputSream
        instream.close()

        // you can now reuse the same `HttpClient` and execute another request
        // using same connection
        httpResponse = client.execute(request);


回答3:

Is it possible that I connect to the service only once at the start, then the connection remains open...

The web server has a role to play in this. If the server "ends" the HTTP response, there is no further communication going to happen on same HTTP call.

It is possible to keep an HTTP connection open, with help of server. In this case, server never really ends the response but keeps writing data to response stream after some time intervals, so client can keep listening.

The new replacement for the above technique is a duplex socket connection. Both client and server can send and receive messages over a socket. Again, both client and server have to support it properly, and necessary handling for connection drops etc has to be there.

There are android specific client implementations available like https://github.com/nkzawa/socket.io-client.java that take care of most of connection management for you.



回答4:

I think you could try to use the AsyncTask class to try to keep your thread open and do what you want, like this:

public class ConnectToWebService extends AsyncTask<Void, Void, Boolean> {

    @Override
    protected Boolean doInBackground(Void... params) { ... }

    @Override
    protected void onPostExecute(final Boolean success) { ... }

    @Override
    protected void onCancelled() { ... }
}

Check the API documentation for more information ;)