gpt4 book ai didi

android - 聊天应用程序用户如何才能再次在线获得离线时发送给他们的消息

转载 作者:可可西里 更新时间:2023-11-01 11:23:54 25 4
gpt4 key购买 nike

我正在开发一个 Android 聊天应用程序,使用 Node Js 和 Redis 来存储消息和用户信息。我正在使用 socket io 进行通信,并使用 Room 将消息存储在本地数据库中。当用户离线时,我希望他们再次在线时收到消息。我的问题是,当用户 A 离线时,用户 B 向他发送了很多消息(比如 5 条消息),当用户 A 再次在线时,他只收到第一条消息,最后一条消息 4 次。这是我正在做的,一旦用户收到消息,我将 Redis 中的消息状态从“已发送”更新为“已送达”。在用户离线的情况下,我将他们的消息存储在 Redis 中,消息状态为“已发送”,再次在线时,我检查他们收到的消息,例如从用户 B 收到的消息,如果他们的状态为“已发送”,我将发送发送给用户,然后更新为“Delivered”,如下代码所示:

      //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();
}


}
});
}

}
});

最佳答案

我通过切换到 RxJava 而不是 AsyncTask 解决了这个问题。该问题与 AsyncTask 有关,因为它有时会影响数据链,而 RxJava 则不是这种情况,如 this link 中所述。 :“AsyncTasks 的另一个问题是,如果您同时运行多个任务。您无法保证它们将按什么顺序完成,从而导致复杂的逻辑来检查所有任务何时完成。更糟糕的是假设一个人会先于另一个完成,直到您遇到使第一个调用变慢的边缘情况,这使得它们以错误的顺序和不希望的结果完成。”

关于android - 聊天应用程序用户如何才能再次在线获得离线时发送给他们的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54430407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com