Как пользователь приложения чата, снова подключившись к сети, может получать сообщения, отправленные ему, когда он был отключен - PullRequest
0 голосов
/ 30 января 2019

Я занимаюсь разработкой приложения для чата Android, используя Node Js и redis для хранения сообщений и информации о пользователях.Я использую сокет io для связи, и Room для хранения сообщений в локальной базе данных.Когда пользователь не в сети, я хочу, чтобы он снова получал свои сообщения онлайн.Моя проблема в том, что когда пользователь A находится в автономном режиме, а пользователь B отправляет ему много сообщений (скажем, например, 5 сообщений), когда пользователь A снова в сети, он получает только первое сообщение и последнее сообщение 4 раза.Вот что я делаю, когда пользователь получает сообщение, я обновляю статус сообщения в Redis с «Отправлено» на «Доставлено».В случае, когда пользователь находится в автономном режиме, я храню его сообщения в Redis со статусом сообщения «Отправлено», и снова в сети я проверяю его сообщения, полученные, например, от пользователя B, если его статус «Отправлено», я доставляюэто пользователю, а затем оно будет обновлено до «Доставлено», как показано в приведенном ниже коде:

      //On this event, we update the socket ID of the sender in Redis so they can 
receive private messages from their contacts
socket.on('sender', (sender, destinat) =>{
tempId = socket.id;
senderId = sender;
users[sender] = sender;
users [destinat] = destinat;

//We also update the user status: online
client.hset(senderId, 'lastSeen', 'Now', function(reply){
           console.log( senderId + reply);
     });

//Stocking to the user socket id 
client.hset(users[sender], 'tempId', tempId, function(){
           console.log("Welcome " + sender);
            console.log("Welcome " + tempId);
  });


 //Getting all the messages of the sender from users

 //If the sender has any messages that hasn't received yet, they'll be sent 
  here
 //the id of each message is compsed of two parts: the phone number of the 
 receiver, and the id of  the message itself 
 (receiverPhoneNumber:idMessage)
  client.keys(users [sender] + ':*', function(err, results) {

      results.forEach(function(key) {


         client.hgetall(key, function(err, reply){

             if(err)
             console.log(err);
             else if(reply){

      //Compare the message status: if not sent, deliver it to receiver once online

                  if('Sent'.localeCompare(reply.status) == 0 && users 
[destinat].localeCompare(reply.fromUser)  == 0) {

                   io.to(tempId).emit('message', reply);


              }  

        }


    });


 });


 });

 });

После получения сообщений от сервера я использую Async, чтобы сохранить их в базе данных комнаты, а затемотобразите их пользователю, как показано в следующем коде

А вот класс AsyncTask:

class AddMessage extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... voids) {


        //Creating a user account
        m = new Message();
        m.setContent( message );
        m.setTime( time );
        m.setUrl( url );
        m.setStatus( status );
        m.setFromUser( fromUser );
        m.setToUser( toUser );
        m.setUsername( receiver.getUsername() );
        //adding to database
        DatabaseClient.getInstance(getContext()).getAppDatabase()
                .messageDao()
                .insert(m);

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        Toast.makeText( getContext(), "Added!", Toast.LENGTH_SHORT ).show();



    }
}

Я проверил, что сообщения с сервера поступают в приложение для Android правильно(путем повторной отправки сообщений на сервер после доставки в приложение).Я считаю, что проблема связана с AsyncTask, но я просто не могу понять, любая помощь очень ценится, большое спасибо.

 //When receving a message
    socket.on("message", new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            if(getActivity() != null){
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        JSONObject data = (JSONObject) args[0];
                        try {
                            //extract data from fired event


                            idMessage = data.getString( "idMessage" );
                            message = data.getString("message");
                            fromUser = data.getString( "fromUser" );
                            toUser = data.getString( "toUser" );
                            time = data.getString( "time" );
                            status = data.getString( "status" );
                            url = data.getString( "url" );             
                             //Here we call asyncTask to Add it to Database
                            addMessage = new AddMessage();
                            addMessage.execute(  );

                            //We emit this event to update the status of 
                            the message to delivered
                            socket.emit( "sent", idMessage, userID );


                        } catch (JSONException e) {
                            e.printStackTrace();
                        }


                    }
                });
            }

        }
    });

1 Ответ

0 голосов
/ 31 января 2019

Я решил проблему, переключившись на RxJava вместо AsyncTask.Эта проблема была связана с AsyncTask, поскольку иногда она влияет на цепочку данных, что не относится к RxJava, как упоминалось в this link : «Другая проблема с AsyncTasks - если у вас несколько запущенныхсразу. У вас нет гарантии, в каком порядке они будут выполнены, в результате сложная логика будет проверять, когда все задачи будут выполнены. Еще хуже то, что одно из них будет выполнено раньше другого, пока вы не столкнетесь с крайним случаем, который делаетПервый вызов медленнее, что делает их завершенными в неправильном порядке и нежелательных результатов. "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...