nkzawa / socket.io-android-chat

A simple chat demo for socket.io and Android
MIT License
2k stars 691 forks source link

Socket Disconnect if (android) app is in background and multiple app opens #45

Open VyasMankar opened 8 years ago

VyasMankar commented 8 years ago

Hi,

We developed a chat application for android using socket.io library, But we are facing one issue.

When we kept app in background socket remains connected, even if we keep it idle for some time, socket doesn't disconnect which is fine, but the problem comes when we open any other app, socket disconnects.

Can you please tell us what can be the problem & solution for that.

Thanks in advance...

sanchitgarg1909 commented 8 years ago

This is probably your phone's issue. When you open multiple apps at a time, the phone clears out RAM by stopping rarely used apps. So the more RAM the phone has the less chances are of this problem to occur. To tackle this problem you could make a service which runs even when the app is removed from the background and check when the socket is disconnected.

pishguy commented 8 years ago

@VyasMankar You can use this solution, i hope to help you

Service:

public class SocketServiceProvider extends Service {
    private Application signalApplication;
    private Realm       realm;

    public static SocketServiceProvider instance = null;

    public static boolean isInstanceCreated() {
        return instance == null ? false : true;
    }

    private final IBinder myBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        public SocketServiceProvider getService() {
            return SocketServiceProvider.this;
        }
    }

    public void IsBendable() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    @Override
    public void onCreate() {
        if (isInstanceCreated()) {
            return;
        }
        super.onCreate();
        realm = Realm.getDefaultInstance();

        signalApplication = (Application) getApplication();

        if (signalApplication.getSocket() == null)
            signalApplication.CHAT_SOCKET = signalApplication.getSocket();

        signalApplication.getSocket().on(Socket.EVENT_CONNECT_ERROR, onConnectError);
        signalApplication.getSocket().on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        signalApplication.getSocket().on(Socket.EVENT_CONNECT, onConnect);

        //@formatter:off
            signalApplication.getSocket().on("message"                   , message);
        //@formatter:on

        EventBus.getDefault().register(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (isInstanceCreated()) {
            return 0;
        }
        super.onStartCommand(intent, flags, startId);
        connectConnection();
        return START_STICKY;
    }

    private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    EventBus.getDefault().post(
                            new EventChangeChatServerStateEvent(EventChangeChatServerStateEvent.chatServerState.connectedToSocket)
                    );
                }
            });
        }
    };

    private Emitter.Listener onDisconnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    EventBus.getDefault().post(
                            new EventChangeChatServerStateEvent(EventChangeChatServerStateEvent.chatServerState.disconnectedFromSocket)
                    );
                }
            });
        }
    };

    private Emitter.Listener onConnectError = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    EventBus.getDefault().post(
                            new EventChangeChatServerStateEvent(EventChangeChatServerStateEvent.chatServerState.flashConnectionIcon)
                    );
                }
            });
        }
    };

    private Emitter.Listener message = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            final JSONObject result = (JSONObject) args[0];
            new Handler(getMainLooper())
                    .post(
                            new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        String username = result.getString("username");
                                        Utils.createNotification(getBaseContext(), ActivityLogin.class, "You have NEW message !!", "( " + username + " )" + "has been requested money", 0);
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }

                    );
        }
    };

    private void connectConnection() {
        instance = this;
        signalApplication.getSocket().connect();
    }

    private void disconnectConnection() {
        instance = null;
        signalApplication.getSocket().disconnect();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (!realm.isClosed())
            realm.close();

        signalApplication.getSocket().off(Socket.EVENT_CONNECT, onConnect);
        signalApplication.getSocket().off(Socket.EVENT_DISCONNECT, onDisconnect);
        signalApplication.getSocket().off(Socket.EVENT_CONNECT_ERROR, onConnectError);
        signalApplication.getSocket().off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);

        //@formatter:off
            signalApplication.getSocket().off("message"                         , message);
        //@formatter:on

        disconnectConnection();
    }

}

my ActivityLogin:

    protected ServiceConnection socketConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBoundService = ((SocketServiceProvider.LocalBinder) service).getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBoundService = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
...
        if (application.getSocket() != null) {
            Log.e("Socket", " is null");
            startService(new Intent(getBaseContext(), SocketServiceProvider.class));
            doBindService();
        }
...

    private void doBindService() {
        if (mBoundService != null) {
            bindService(new Intent(ActivityLogin.this, SocketServiceProvider.class), socketConnection, Context.BIND_AUTO_CREATE);
            mIsBound = true;
            mBoundService.IsBendable();
        }
    }

and Application class:

public class Application extends android.app.Application {

    public static final boolean DEBUG = true;
    public static Application application;

    private static Context context;

    public static String    packageName;
    public static Resources resources;
    public static Socket    CHAT_SOCKET;

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
    }

    @Override
    public void onCreate() {
        super.onCreate();

        //@formatter:off
            resources   = this.getResources();
            context     = getApplicationContext();
            packageName = getPackageName();
        //@formatter:on

        IO.Options opts = new IO.Options();
        opts.forceNew = true;
        opts.reconnection = true;

        try {
            CHAT_SOCKET = IO.socket(ClientSettings.getChatAddress(), opts);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            Log.e("SOCKET.IO ", e.getMessage());
        }

    }

    public static Context getContext() {
        return context;
    }

    public Socket getSocket() {
        return CHAT_SOCKET;
    }
}

How can i Emmit:

JSONObject jsonObject = new JSONObject();
try {
    jsonObject.put("fromUsername", username);
    jsonObject.put("userEwalletNumber", myChooesdEwallet);
    jsonObject.put("amount", amount);
    application.getSocket().emit("requestMoney", jsonObject);
} catch (JSONException e) {
    e.printStackTrace();
}
VyasMankar commented 8 years ago

Hi, Thanks give me a solution.i will try and let

On Mon, Aug 8, 2016 at 8:03 PM, Mahdi Pishguy notifications@github.com wrote:

@VyasMankar https://github.com/VyasMankar You can use this solution, i hope to help you

Service:

public class SocketServiceProvider extends Service { private Application signalApplication; private Realm realm;

public static SocketServiceProvider instance = null;

public static boolean isInstanceCreated() {
    return instance == null ? false : true;
}

private final IBinder myBinder = new LocalBinder();

public class LocalBinder extends Binder {
    public SocketServiceProvider getService() {
        return SocketServiceProvider.this;
    }
}

public void IsBendable() {
}

@Override
public IBinder onBind(Intent intent) {
    return myBinder;
}

@Override
public void onCreate() {
    if (isInstanceCreated()) {
        return;
    }
    super.onCreate();
    realm = Realm.getDefaultInstance();

    signalApplication = (Application) getApplication();

    if (signalApplication.getSocket() == null)
        signalApplication.CHAT_SOCKET = signalApplication.getSocket();

    signalApplication.getSocket().on(Socket.EVENT_CONNECT_ERROR, onConnectError);
    signalApplication.getSocket().on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
    signalApplication.getSocket().on(Socket.EVENT_CONNECT, onConnect);

    //@formatter:off
        signalApplication.getSocket().on("message"                   , message);
    //@formatter:on

    EventBus.getDefault().register(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (isInstanceCreated()) {
        return 0;
    }
    super.onStartCommand(intent, flags, startId);
    connectConnection();
    return START_STICKY;
}

private Emitter.Listener onConnect = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(
                        new EventChangeChatServerStateEvent(EventChangeChatServerStateEvent.chatServerState.connectedToSocket)
                );
            }
        });
    }
};

private Emitter.Listener onDisconnect = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(
                        new EventChangeChatServerStateEvent(EventChangeChatServerStateEvent.chatServerState.disconnectedFromSocket)
                );
            }
        });
    }
};

private Emitter.Listener onConnectError = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(
                        new EventChangeChatServerStateEvent(EventChangeChatServerStateEvent.chatServerState.flashConnectionIcon)
                );
            }
        });
    }
};

private Emitter.Listener message = new Emitter.Listener() {
    @Override
    public void call(final Object... args) {
        final JSONObject result = (JSONObject) args[0];
        new Handler(getMainLooper())
                .post(
                        new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    String username = result.getString("username");
                                    Utils.createNotification(getBaseContext(), ActivityLogin.class, "You have NEW message !!", "( " + username + " )" + "has been requested money", 0);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                );
    }
};

private void connectConnection() {
    instance = this;
    signalApplication.getSocket().connect();
}

private void disconnectConnection() {
    instance = null;
    signalApplication.getSocket().disconnect();
}

@Override
public void onDestroy() {
    super.onDestroy();

    if (!realm.isClosed())
        realm.close();

    signalApplication.getSocket().off(Socket.EVENT_CONNECT, onConnect);
    signalApplication.getSocket().off(Socket.EVENT_DISCONNECT, onDisconnect);
    signalApplication.getSocket().off(Socket.EVENT_CONNECT_ERROR, onConnectError);
    signalApplication.getSocket().off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);

    //@formatter:off
        signalApplication.getSocket().off("message"                         , message);
    //@formatter:on

    disconnectConnection();
}

}

my ActivityLogin:

if (application.getSocket() != null) { Log.e("Socket", " is null"); startService(new Intent(getBaseContext(), SocketServiceProvider.class)); doBindService(); }

and Application class:

public class Application extends android.app.Application {

public static final boolean DEBUG = true;
public static Application application;

private static Context context;

public static String    packageName;
public static Resources resources;
public static Socket    CHAT_SOCKET;

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
}

@Override
public void onCreate() {
    super.onCreate();

    //@formatter:off
        resources   = this.getResources();
        context     = getApplicationContext();
        packageName = getPackageName();
    //@formatter:on

    IO.Options opts = new IO.Options();
    opts.forceNew = true;
    opts.reconnection = true;

    try {
        CHAT_SOCKET = IO.socket(ClientSettings.getChatAddress(), opts);
    } catch (URISyntaxException e) {
        e.printStackTrace();
        Log.e("SOCKET.IO ", e.getMessage());
    }

}

public static Context getContext() {
    return context;
}

public Socket getSocket() {
    return CHAT_SOCKET;
}

}

How can i Emmit:

JSONObject jsonObject = new JSONObject(); try { jsonObject.put("fromUsername", username); jsonObject.put("userEwalletNumber", myChooesdEwallet); jsonObject.put("amount", amount); application.getSocket().emit("requestMoney", jsonObject); } catch (JSONException e) { e.printStackTrace(); }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nkzawa/socket.io-android-chat/issues/45#issuecomment-238256582, or mute the thread https://github.com/notifications/unsubscribe-auth/AJu0IihBfyP4XObDzshAz9fy-YZFHGKYks5qdz5UgaJpZM4JXSA4 .

pishguy commented 8 years ago

@sanchitgarg1909 Hi sir, my application's service disconnected after close app.i dont have any multiple and i'm using one service and appliaction on phone, but after closing application socket disconnected and dont trigger

pelcom commented 7 years ago

i will like to know where the EventChangeChatServerStateEvent class comes from and what it does.

pishguy commented 7 years ago

@pelcom EventChangeChatServerStateEvent class is only simple class to pass data with EventBus library, in this class i pass only simple enum

pelcom commented 7 years ago

I haven't properly understood the EventBus library i will like to know how to access the events save in the EventBus or better still see a sample of what could be placed in the EventChangeChatServerStateEvent .

pishguy commented 7 years ago

@pelcom ok, look at this code:

public class EventChangeChatServerStateEvent {
    private chatServerState state;

    public EventChangeChatServerStateEvent(chatServerState state) {
        this.state = state;
    }

    public chatServerState getState() {
        return state;
    }

    public enum chatServerState {
        connectedToSocket,
        disconnectedFromSocket,
        flashConnectionIcon
    }
}

SampleActivity:

public class SampleActivity extends AppCompatActivity {
    ...
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
    }

    @Override
    public void onResume() {
        super.onResume();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe
    public void onEvent(EventChangeChatServerStateEvent event) {
        switch (event.getState()) {
            case connectedToSocket:
                connectionState(new ConnectionTypes(ConnectionTypes.connectionType.connectedToSocket));
                break;
            case disconnectedFromSocket:
                connectionState(new ConnectionTypes(ConnectionTypes.connectionType.disconnectedFromSocket));
                break;
            case flashConnectionIcon:
                connectionState(new ConnectionTypes(ConnectionTypes.connectionType.prepareConnection));
                break;
        }
    }
}
pelcom commented 7 years ago

@tux-world thank you so much for the sample provided. in fact i now understand the usage of EventBus properly.

pishguy commented 7 years ago

Your welcome

kushanshah11 commented 6 years ago

Hi @MahdiPishguy can you please share full code of service along with all things ?

it will help me a lot.

Thank you.

pishguy commented 6 years ago

@kushanshah11

yes sure

import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.birbit.android.jobqueue.JobManager;
import com.onehilltech.concurrent.CompletionCallback;
import com.onehilltech.concurrent.Concurrent;
import com.onehilltech.concurrent.Task;
import com.onehilltech.concurrent.android.AndroidCompletionCallback;
import com.raizlabs.android.dbflow.config.FlowManager;
import com.raizlabs.android.dbflow.sql.language.SQLite;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import ir.pishguy.cafealachiqpro.BuildConfig;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Alachiq;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Dagger.Components.ApplicationComponent;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Dagger.Components.DaggerApplicationComponent;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Events.Broadcasts.ConnectivityReceiver;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Events.Broadcasts.EventNetworkConnectionStateEvent;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Events.ConnectivityTester;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Helpers.AndroidUtilities;
import ir.pishguy.cafealachiqpro.CoreAlachiq.Helpers.SP;
import ir.pishguy.cafealachiqpro.R;
import ir.pishguy.cafealachiqpro.Schema.ContentModels.CafeWebsContents;
import ir.pishguy.cafealachiqpro.Schema.ContentModels.CafeWebsContents_Table;
import ir.pishguy.cafealachiqpro.Schema.ContentModels.Text;
import ir.pishguy.cafealachiqpro.Schema.ContentModels.Text_Table;
import ir.pishguy.cafealachiqpro.Schema.DbHelper;
import ir.pishguy.cafealachiqpro.Schema.Models.AlachiqCafeWebs;
import ir.pishguy.cafealachiqpro.Schema.Models.AppDatabase;
import ir.pishguy.cafealachiqpro.Schema.Models.CafeWebMembers;
import ir.pishguy.cafealachiqpro.Schema.Models.CafeWebMembers_Table;
import ir.pishguy.cafealachiqpro.Schema.Models.CafeWebPostsCategories;
import ir.pishguy.cafealachiqpro.Schema.Models.CafeWebPostsCategories_Table;
import ir.pishguy.cafealachiqpro.Schema.Models.UserInformation;
import ir.pishguy.cafealachiqpro.Ui.ActivityStartUpApplication;
import ir.pishguy.cafealachiqpro.Ui.Main.view.ActivityMain;

/**
 * Created by Mahdi Pishguy @pishguy@gmail.com on 6/11/16.
 */
public class SocketServiceProvider extends Service implements ConnectivityReceiver.ConnectivityReceiverListener {
    @Inject
    transient Socket socket;

    @Inject
    transient JobManager taskManager;

    @Inject
    transient Handler handler;

    public static final String ACTION_UPDATE_POSTS_DATA             = BuildConfig.APPLICATION_ID + ":action_post_data";
    public static final String EXTRA_POST_ACTION                    = BuildConfig.APPLICATION_ID + ":extra_post_action";
    public static final String ACTION_NEW_POST_INSERTED_TO_CAFE_WEB = BuildConfig.APPLICATION_ID + ":action_new_post_inserted_to_cafe_web";
    public static final String ACTION_GET_NEW_POST                  = BuildConfig.APPLICATION_ID + ":action_get_new_post";
    public static final String ACTION_NEW_POST_RECEIVED             = BuildConfig.APPLICATION_ID + ":action_new_post_received";

    public static final String                EXTRA_POST_INFO     = "extra_post_info";
    public static final String                EXTRA_POST_POSITION = "extra_post_position";
    private final       IBinder               binder              = new LocalBinder();
    public static       SocketServiceProvider instance            = null;
    private Alachiq               alachiq;
    private ApplicationComponent  component;
    private LocalBroadcastManager mLocalBroadcastManager;
    private NotificationManager   notificationManager;
    private int counter = 0;

    private class BroadcastDataObject {
        public JSONObject jsonObject;
        public JSONArray  jsonArray;
        public int        position;
        public String     action;
        public int        requestLatestIdOfPost;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        if (isInstanceCreated()) {
            return;
        }

        alachiq = (Alachiq) getApplication();

        component = DaggerApplicationComponent.builder()
                .githubApplicationComponent(alachiq.getApplication().getComponent())
                .build();
        component.inject(this);

        Alachiq.getInstance().setConnectivityListener(this);

        connectConnection();

        mLocalBroadcastManager = LocalBroadcastManager.getInstance(getBaseContext());

        notificationManager = (NotificationManager)
                getSystemService(NOTIFICATION_SERVICE);

        onSockets();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        if (intent != null && intent.getAction() != null) {
            String                  action      = intent.getAction();
            BaseDataBindInformation information = (BaseDataBindInformation) intent.getSerializableExtra(EXTRA_POST_INFO);
            switch (action) {
                case ACTION_GET_NEW_POST:
                    updateNewPosts(-1);
            }
        }

        return START_STICKY;
    }

    public static boolean isInstanceCreated() {
        return instance == null ? false : true;
    }

    public static void receiveDataOnFirstTime(Context context) {
        Intent intent = new Intent(context, SocketServiceProvider.class);
        intent.setAction(ACTION_GET_NEW_POST);
        context.startService(intent);
    }

    //public static void setPostVisit(int postId)

    //<editor-fold desc="onConnect">
    private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.e("onConnect", " ......");
            connectToServer();

            // postUnPublishedPosts();
        }
    };

    private void connectToServer() {
        EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.connectedToServerApp));
        if (!AndroidUtilities.checkPhoneStatusPermission(getBaseContext()) && SP.getInstance().getString(SP.SharedPrefsTypes.deviceId).length() == 0) {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
                //skip to emit socket
            } else {
                startAlachiqService();
            }
        } else {
            startAlachiqService();
        }
    }
    //</editor-fold>

    //<editor-fold desc="startAlachiqService">
    private void startAlachiqService() {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                connectConnection();
            }
        });
    }
    //</editor-fold>

    private Emitter.Listener onDisconnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.e("onDisconnect", " ......");
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.disconnectedFromServerApp));
                }
            });
        }
    };

    private Emitter.Listener onConnectError = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.e("onConnectError", " ......");
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.connecting));
                }
            });
        }
    };

    private void connectConnection() {
        instance = this;
        socket.connect();

        UserInformation user = SQLite.select().from(UserInformation.class).querySingle();
        if (user != null && user.isUserActiveState()) {
            updateNewPosts(-1);
        }
    }

    private void postUnPublishedPosts() {
        final List<Text> unPublishedPosts = SQLite.select().from(Text.class)
                .where(Text_Table.published.is(false)).queryList();

        counter = 0;
        final Runnable runnable = new Runnable() {
            public void run() {
                Log.e(" counter ", counter + "  " + unPublishedPosts.size());
                if (counter < unPublishedPosts.size()) {
                    CafeWebsContents cafeWebsContents =
                            SQLite.select().from(CafeWebsContents.class)
                                    .where(CafeWebsContents_Table.id.eq(unPublishedPosts.get(counter).getParentId())).querySingle();

                    CafeWebPostsCategories defaultCategory =
                            SQLite.select().from(CafeWebPostsCategories.class)
                                    .where(CafeWebPostsCategories_Table.cafeServerId.eq(cafeWebsContents.getCafeWebServerId())).querySingle();

                    Intent msgIntent = new Intent(getBaseContext(), PostMessageService.class);
                    msgIntent.putExtra("text", unPublishedPosts.get(counter).getPlainText());
                    msgIntent.putExtra("categoryId", defaultCategory.getCategoryServerId() + "");
                    msgIntent.putExtra("selectedCafeWeb", cafeWebsContents.getCafeWebServerId() + "");
                    msgIntent.putExtra("localId", unPublishedPosts.get(counter).getParentId() + "");
                    startService(msgIntent);

                    counter++;
                    handler.postDelayed(this, 500);
                } else
                    handler.removeCallbacksAndMessages(null);
            }
        };
        handler.post(runnable);
    }

    private void updateNewPosts(final int chafeWebId) {
        UserInformation user = SQLite.select().from(UserInformation.class).querySingle();
        if (user == null || user != null && !user.isUserActiveState()) {
            return;
        }
        if (socket != null && socket.connected() && ConnectivityTester.isConnected(getBaseContext())) {
            Concurrent.getDefault()
                    .series(new Task("task-firstConnect") {
                        @Override
                        public void run(Object unused, final CompletionCallback callback) {
                            socket.once("firstConnectRes", new Emitter.Listener() {
                                @Override
                                public void call(Object... args) {
                                    BroadcastDataObject object = new BroadcastDataObject();
                                    object.jsonObject = (JSONObject) args[0];
                                    object.action = ACTION_NEW_POST_INSERTED_TO_CAFE_WEB;
                                    object.position = 0;
                                    object.requestLatestIdOfPost = 1;
                                    callback.done(object);
                                }
                            });

                            JSONObject data     = new JSONObject();
                            JSONArray  dataMata = new JSONArray();
                            if (chafeWebId != -1) {
                                JSONObject joinedCafeInformation = new JSONObject();
                                try {
                                    CafeWebsContents latestId =
                                            SQLite.select()
                                                    .from(CafeWebsContents.class)
                                                    .where(CafeWebsContents_Table.cafeWebServerId.eq(chafeWebId))
                                                    .orderBy(CafeWebsContents_Table.id, false)
                                                    .querySingle();
                                    joinedCafeInformation.put("ChannelId", chafeWebId);
                                    joinedCafeInformation.put("LastId", latestId == null ? 0 : latestId.getContentServerId());
                                    dataMata.put(joinedCafeInformation);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            } else {
                                try {
                                    List<AlachiqCafeWebs> list =
                                            SQLite.select()
                                                    .from(AlachiqCafeWebs.class).queryList();
                                    if (list != null) {
                                        for (int p = 0; p < list.size(); p++) {
                                            List<CafeWebMembers> userJoined = list.get(p).cafeWebMembersList;
                                            for (int i = 0; i < userJoined.size(); i++) {
                                                JSONObject joinedCafeInformation = new JSONObject();
                                                CafeWebsContents latestId =
                                                        SQLite.select()
                                                                .from(CafeWebsContents.class)
                                                                .where(CafeWebsContents_Table.cafeWebServerId.eq(list.get(p).getServerCafeId()))
                                                                .orderBy(CafeWebsContents_Table.contentServerId, false)
                                                                .querySingle();
                                                joinedCafeInformation.put("ChannelId", list.get(p).getServerCafeId());
                                                joinedCafeInformation.put("LastId", latestId == null ? 0 : latestId.getContentServerId());

                                                dataMata.put(joinedCafeInformation);
                                            }
                                        }
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                            try {
                                data.put("DeviceId",
                                        SP.getInstance().getString(SP.SharedPrefsTypes.deviceId).length() != 0 ?
                                                SP.getInstance().getString(SP.SharedPrefsTypes.deviceId) :
                                                AndroidUtilities.getDeviceIMEI(getBaseContext()));
                                data.put("Data", dataMata);
                                socket.emit("firstConnect", data);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            EventBus.getDefault().post(new
                                    EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.updating));
                        }
                    })
                    .execute(new AndroidCompletionCallback<Map<String, Object>>() {
                        @Override
                        public void onPostComplete(Map<String, Object> receivedData) {
                            BroadcastDataObject data = (BroadcastDataObject) receivedData.get("task-firstConnect");
                            try {
                                boolean result = data.jsonObject.getBoolean("result");
                                if (result) {
                                    JSONArray contents = data.jsonObject.getJSONArray("contents");
                                    for (int p = 0; p < contents.length(); p++) {
                                        JSONObject contentsData      = contents.getJSONObject(p);
                                        JSONArray  contentCategories = contentsData.getJSONArray("category");

                                        if (contentsData.isNull("category") || contentCategories.length() < 1) {
                                            return;
                                        }

                                        DbHelper.storeAndUpdateCafeWebCategories(contentCategories);

                                        //<editor-fold desc="post count">
                                        if (contentsData.getJSONArray("posts").length() > 0) {
                                            JSONObject parentPostInformation = contentsData.getJSONArray("posts").getJSONObject(0);

                                            int     contentServerId = parentPostInformation.getInt("id");
                                            int     categoryId      = parentPostInformation.getInt("categoryId");
                                            int     cafeWebServerId = parentPostInformation.getInt("channelId");
                                            boolean postForVipUsers = false;

                                            if (parentPostInformation.isNull("vip")) {
                                                postForVipUsers = false;
                                            } else if (!parentPostInformation.isNull("vip") && parentPostInformation.getInt("vip") == 0) {
                                                postForVipUsers = false;
                                            } else if (!parentPostInformation.isNull("vip") && parentPostInformation.getInt("vip") == 1) {
                                                postForVipUsers = true;
                                            }

                                            CafeWebsContents foundDuplicate = SQLite.select().from(CafeWebsContents.class)
                                                    .where(CafeWebsContents_Table.contentServerId.eq(contentServerId))
                                                    .querySingle();

                                            CafeWebPostsCategories categoryIdRow =
                                                    SQLite.select().from(CafeWebPostsCategories.class)
                                                            .where(CafeWebPostsCategories_Table.categoryServerId.eq(categoryId))
                                                            .querySingle();
                                            long lastId;
                                            if (foundDuplicate == null) {
                                                CafeWebsContents cafeWebsContents = new CafeWebsContents();

                                                cafeWebsContents.setCafeWebServerId(cafeWebServerId);
                                                cafeWebsContents.setContentServerId(contentServerId);
                                                cafeWebsContents.setContentType(parentPostInformation.getString("contentType"));
                                                cafeWebsContents.setParentId(categoryIdRow.getId());
                                                cafeWebsContents.setCategoryServerId(categoryId + "");
                                                lastId = cafeWebsContents.insert();
                                            } else {
                                                foundDuplicate.setContentServerId(cafeWebServerId);
                                                foundDuplicate.setContentType(parentPostInformation.getString("contentType"));
                                                foundDuplicate.setParentId(categoryIdRow.getId());
                                                foundDuplicate.setCategoryServerId(categoryId + "");
                                                foundDuplicate.update();
                                                lastId = foundDuplicate.getId();
                                            }

                                            //<editor-fold desc="if">
                                            if (lastId != 0) {
                                                if (!parentPostInformation.isNull("ChannelFileContainer")) {
                                                    DbHelper.storeFilePost(
                                                            parentPostInformation.getJSONObject("ChannelFileContainer"),
                                                            lastId, contentServerId, categoryId, cafeWebServerId);
                                                } else if (!parentPostInformation.isNull("ChannelImageContainer")) {
                                                    DbHelper.storeImagePost(
                                                            parentPostInformation.getJSONObject("ChannelImageContainer"),
                                                            lastId, contentServerId, categoryId, cafeWebServerId);
                                                } else if (!parentPostInformation.isNull("ChannelMusicContainer")) {
                                                    DbHelper.storeMusicPost(
                                                            parentPostInformation.getJSONObject("ChannelMusicContainer"),
                                                            lastId, contentServerId, categoryId, cafeWebServerId);
                                                } else if (!parentPostInformation.isNull("ChannelVideoContainer")) {
                                                    DbHelper.storeVideoPost(
                                                            parentPostInformation.getJSONObject("ChannelVideoContainer"),
                                                            lastId, contentServerId, categoryId, cafeWebServerId);
                                                } else if (!parentPostInformation.isNull("ChannelPlainTextContainer")) {
                                                    DbHelper.storeTextPost(
                                                            parentPostInformation.getJSONObject("ChannelPlainTextContainer"),
                                                            lastId, contentServerId, categoryId, cafeWebServerId, postForVipUsers, false);

                                                    if (!parentPostInformation.isNull("Rate")) {
                                                        Text text = SQLite.select().from(Text.class).where(Text_Table.serverId.eq(contentServerId)).querySingle();
                                                        if (text != null) {
                                                            text.setPostRate(
                                                                    parentPostInformation.isNull("totalRate") ? 0 : parentPostInformation.getInt("totalRate"));
                                                            text.setPostVisit(
                                                                    parentPostInformation.isNull("totalVisit") ? 0 : parentPostInformation.getInt("totalVisit"));
                                                            text.setPrice(
                                                                    parentPostInformation.isNull("price") ? "" : parentPostInformation.getInt("price") + "");

                                                            if (parentPostInformation.getJSONArray("Rate").length() == 0) {
                                                                text.setPostRate(0);
                                                                text.setPostRateState(0);
                                                                text.update();
                                                            } else {
                                                                JSONObject postRateInformation =
                                                                        parentPostInformation.getJSONArray("Rate").getJSONObject(0);
                                                                int    rateStatus       = 0;
                                                                String rateStatusString = postRateInformation.getString("rateType");

                                                                if (rateStatusString.equals("Canceled") || rateStatusString.isEmpty()) {
                                                                    rateStatus = 0;
                                                                } else if (rateStatusString.equals("Increase")) {
                                                                    rateStatus = 1;
                                                                } else if (rateStatusString.equals("Reduce")) {
                                                                    rateStatus = -1;
                                                                }

                                                                text.setPostRateState(rateStatus);
                                                                text.update();
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            //</editor-fold>
                                        }
                                        //</editor-fold>

                                        //<editor-fold desc="between Posts">
                                        if (contentsData.getJSONArray("betweenPosts").length() > 0) {
                                            JSONArray betweenPosts = contentsData.getJSONArray("betweenPosts");
                                            for (int i = 0; i < betweenPosts.length(); i++) {
                                                JSONObject parentPostInformation = contentsData.getJSONArray("betweenPosts").getJSONObject(i);

                                                int    contentsServerId = parentPostInformation.getInt("id");
                                                int    cafeWebServerId  = contentsData.getInt("channelId");
                                                int    categoryId       = parentPostInformation.getInt("categoryId");
                                                String contentType      = parentPostInformation.getString("contentType");

                                                Log.e("BETWEEN-categoryId", categoryId + "");
                                                CafeWebsContents foundDuplicate = SQLite.select().from(CafeWebsContents.class)
                                                        .where(CafeWebsContents_Table.contentServerId.eq(contentsServerId))
                                                        .querySingle();

                                                CafeWebPostsCategories categoryIdRow =
                                                        SQLite.select().from(CafeWebPostsCategories.class)
                                                                .where(CafeWebPostsCategories_Table.categoryServerId.eq(categoryId))
                                                                .querySingle();
                                                long lastId;
                                                if (foundDuplicate == null) {
                                                    CafeWebsContents cafeWebsContents = new CafeWebsContents();

                                                    cafeWebsContents.setCafeWebServerId(cafeWebServerId);
                                                    cafeWebsContents.setContentServerId(contentsServerId);
                                                    cafeWebsContents.setContentType(parentPostInformation.getString("contentType"));
                                                    cafeWebsContents.setParentId(categoryIdRow.getId());
                                                    cafeWebsContents.setCategoryServerId(categoryId + "");

                                                    lastId = cafeWebsContents.insert();
                                                } else {
                                                    foundDuplicate.setContentServerId(cafeWebServerId);
                                                    foundDuplicate.setContentType(parentPostInformation.getString("contentType"));
                                                    foundDuplicate.setParentId(categoryIdRow.getId());
                                                    foundDuplicate.setCategoryServerId(categoryId + "");

                                                    foundDuplicate.update();
                                                    lastId = foundDuplicate.getId();
                                                }

                                                if (lastId != 0) {
                                                    if (contentType.equals("file")) {
                                                        DbHelper.storeEmptyFilePost(lastId, contentsServerId, categoryId, cafeWebServerId);
                                                    } else if (contentType.equals("image")) {
                                                        DbHelper.storeEmptyImagePost(lastId, contentsServerId, categoryId, cafeWebServerId);
                                                    } else if (contentType.equals("music")) {
                                                        DbHelper.storeEmptyMusicPost(lastId, contentsServerId, categoryId, cafeWebServerId);
                                                    } else if (contentType.equals("video")) {
                                                        DbHelper.storeEmptyVideoPost(lastId, contentsServerId, categoryId, cafeWebServerId);
                                                    } else if (contentType.equals("text")) {
                                                        DbHelper.storeEmptyTextPost(lastId, contentsServerId, categoryId, cafeWebServerId);
                                                    }
                                                }
                                            }
                                        }
                                        //</editor-fold>
                                    }
                                } else {
                                    String errorCode = data.jsonObject.getString("errorCode");
                                    if (!errorCode.isEmpty()) {
                                        switch (Integer.parseInt(errorCode)) {
                                            case 1: //InternalError
                                                break;
                                            case 8:
                                                FlowManager.getDatabase(AppDatabase.class).reset();
                                                startActivity(
                                                        new Intent(SocketServiceProvider.this, ActivityStartUpApplication.class)
                                                                .putExtra("flashMessage", true)
                                                );
                                                break;
                                        }
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                                Log.e("task-firstConnect", e.getMessage());
                            }
                            EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.connectedToServerApp));
                            sendBroadCast(data.action);
                        }

                        @Override
                        public void onPostCancel() {
                        }

                        @Override
                        public void onPostFail(Throwable throwable) {
                        }
                    });
        }
    }

    private void sendBroadCast(String action) {
        Intent intent = new Intent();
        intent.setAction(ACTION_UPDATE_POSTS_DATA);
        intent.putExtra(EXTRA_POST_ACTION, action);
        mLocalBroadcastManager.sendBroadcast(intent);
    }

    private void disconnectConnection() {
        instance = null;
        if (socket != null) socket.disconnect();
    }

    private void offSockets() {
        socket.off(socket.EVENT_CONNECT, onConnect);
        socket.off(socket.EVENT_DISCONNECT, onDisconnect);
        socket.off(socket.EVENT_CONNECT_ERROR, onConnectError);
        socket.off(socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        socket.off("message", onMessage);
    }

    private void onSockets() {
        socket.on(socket.EVENT_CONNECT_ERROR, onConnectError);
        socket.on(socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        socket.on(socket.EVENT_CONNECT, onConnect);
        socket.on("message", onMessage);
    }

    //<editor-fold desc="onMessage">
    private Emitter.Listener onMessage = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            final JSONObject data = (JSONObject) args[0];
            Log.e("message ", data.toString());

            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    UserInformation thisUserInfo = DbHelper.getUserInfo();
                    try {
                        CafeWebMembers cafeWebMembers = SQLite.select()
                                .from(CafeWebMembers.class)
                                .where(CafeWebMembers_Table.userUniqueId.eq(thisUserInfo.getUserUniqueId()))
                                .and(CafeWebMembers_Table.cafeId.eq(Integer.valueOf(data.getString("channelId"))))
                                .querySingle();
                        if (cafeWebMembers != null && cafeWebMembers.getIsAdmin() == 0) { // user is not admin
                            updateNewPosts(Integer.valueOf(data.getString("channelId")));
                            if (!Alachiq.isForeground()) {
                                AndroidUtilities.createNotification(
                                        getBaseContext(),
                                        ActivityMain.class,
                                        AndroidUtilities.getString(R.string.you_have_message, getBaseContext()),
                                        AndroidUtilities.getString(R.string.alachiq_waiting_for_you, getBaseContext()),
                                        1,
                                        notificationManager
                                );
                            } else {
                                sendBroadCast(ACTION_NEW_POST_RECEIVED);
                            }
                        } else {
                            updateNewPosts(Integer.valueOf(data.getString("channelId")));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.e("onMessage", e.getMessage());
                    }
                }
            });
        }
    };
    //</editor-fold>

    public class LocalBinder extends Binder {
        public SocketServiceProvider getService() {
            return SocketServiceProvider.this;
        }
    }

    public static class BaseDataBindInformation implements Serializable {
        private int    postParentServerId;
        private int    postServerId;
        public  int    position;
        public  String rate;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        offSockets();
    }

    @Override
    public void onNetworkConnectionChanged(boolean isConnected) {
        if (isConnected) {
            EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.connected));
            connectToServer();
            //connectConnection();
        } else {
            EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.disconnected));
            disconnectConnection();
        }
    }

}
primalbet commented 5 years ago

@MahdiPishguy what is a realm?

Zulqurnain commented 4 years ago

@MahdiPishguy what is a realm?

Realm is fast and easy to use DB library

CoolMind commented 4 years ago

@MahdiPishguy, should we use Service now? What would be better these days?