Thiago
Thiago

Reputation: 13302

Android WebSocket Services making multiple connections

I have created a Web Socket Service. but it keeping making multiple connection

I just want the app to make one connection, unless the network connection drops then make another. But right now, it makes one connection, if I press the home button on the phone. and go back on the app, it will make another connection.

Thanks for your help guys .

onCreate... of my MainActivity

Intent startServiceIntent = new Intent(this, WebSocketServices.class);
        startService(startServiceIntent);

Manifest

<!-- WebSocket -->
<receiver 
    android:name="com.example.basicplayerapp.core.NetworkReceiver">
   <intent-filter >
       <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
       <action android:name="android.intent.action.BOOT_COMPLETED" />
   </intent-filter> 
</receiver>
<service android:name="com.example.basicplayerapp.core.WebSocketServices"></service>

NetworkReceiver

public class NetworkReceiver extends BroadcastReceiver {
    public static final String TAG = HomeActivity.class.getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent) {         
        ConnectivityManager conn =  (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = conn.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
            Log.i(TAG, "connected");

            Intent startServiceIntent = new Intent(context, WebSocketServices.class);
            context.startService(startServiceIntent);

        } 
        else if(networkInfo != null){
            NetworkInfo.DetailedState state = networkInfo.getDetailedState();
            Log.i(TAG, state.name());
        }
        else {
            Log.i(TAG, "lost connection");

        }


    }//end onReceive    
};//end NetworkReceiver

WebsocketServices

public class WebSocketServices extends IntentService {
    public static final String TAG = WebSocketServices.class.getSimpleName();

    private static  String SOCKET_ADDR = "http://171.0.0.1:8080";
    private String message = null;
    private WebSocket socket = null;

    public WebSocketServices() {
        super("DownloadService");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(TAG, "onHandleIntent");

        //SOCKET_ADDR = intent.getStringExtra("ip");

        if(socket==null || !socket.isOpen() || socket.isPaused())
        connectToPASocket(SOCKET_ADDR);

        Log.d(TAG,"Service Invoke Function");
    }//end onHandleIntent






    //=====================================================================================
    // Socket connection 
    //===================================================================================== 
    private void connectToPASocket(String SOCKET_ADDR) {
        Log.i(TAG, "connectToPASocket()");

        // Checking
        if (socket != null && socket.isOpen()) return;


        // Initiate web socket connection
        AsyncHttpClient.getDefaultInstance().websocket(SOCKET_ADDR, null,
                new AsyncHttpClient.WebSocketConnectCallback() {
                    @Override
                    public void onCompleted(Exception ex, WebSocket webSocket) {
                        Log.i(TAG, "onCompleted");

                        if (ex != null) {
                            Log.i(TAG, "onCompleted > if (ex != null)");
                            ex.printStackTrace();
                            return;
                        }

                        socket = webSocket;
                        socket.setStringCallback(new StringCallback() {
                            public void onStringAvailable(String s) {
                                Log.i(TAG, "socket.setStringCallback > onStringAvailable - s => " + s);

                                System.out.println("I got a string: " + s);
                                message = s;



                            }// end onStringAvailable
                        });// end socket.setStringCallback

                        socket.setDataCallback(new DataCallback() { // Find out what this does
                            @Override
                            public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
                                Log.i(TAG, "socket.setDataCallback > onDataAvailable | emitter=> " + emitter + " | bb => " + bb);

                                System.out.println("I got some bytes!");
                                // note that this data has been read
                                bb.recycle();
                            }
                        });// end webSocket.setDataCallback

                    }// end onCompleted
                });// end AsyncHttpClient.getDefaultInstance()
    }// end connectToPASocket
}//end WebSocketServices

Upvotes: 8

Views: 4938

Answers (4)

Mr T
Mr T

Reputation: 1499

MrT, I had a similar probelm.

Dont use intentService. Just use Service. Because once the intentService has been done, it will finish itself.

After you change to Service, What you can do, is to use boolean to check if your service has been started like so:

boolean isSockeStarted = false;



  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
...


        if (socket == null || !socket.isOpen() || socket.isPaused()) {

            if (isSockeStarted) { //not started
            } else {
                isSockeStarted = true;
            }
        }
....

That mean, this service will only start once. until you kill it manually.

it worked for me, try and let me know.

Upvotes: 2

Ashton Engberg
Ashton Engberg

Reputation: 6109

You should use a regular service, not an intent service. Once intent service is finished, it finishes. A service can start a background thread that will maintain the web socket connection until you explicitly kill it; or the OS reclaims the service's memory (in which you'd need to start it again).

Upvotes: 1

Soroush
Soroush

Reputation: 126

It happened because after your returning to app onCreate will be call for second time and it make another connection to socket . so you can simple don't start another service if your IntentService is still running , something like this :

onCreate... of MainActivity

if(isMyServiceRunning(WebSocketServices.class)){
Intent startServiceIntent = new Intent(this, WebSocketServices.class);
    startService(startServiceIntent);
}

method to see if your service is running

private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager)    getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
    if (serviceClass.getName().equals(service.service.getClassName())) {
        return true;
    }
}
return false;
}

Upvotes: 2

Daniel Petrov
Daniel Petrov

Reputation: 38

Try filtering the actions in onReceive Method - something like if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction()))

Upvotes: 2

Related Questions