Я занимаюсь разработкой приложения для чата 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();
}
}
});
}
}
});