显示已交付和蓝色滴答声,例如Whats App

时间:2018-08-17 05:13:40

标签: javascript node.js socket.io chat messaging

我已经使用套接字创建了一个应用程序...我能够使用套接字连接来管理两个人之间的对话。

这里是代码

用户模型

const schema = new Mongoose.Schema({
  firstName: { type: String, default: '', trim: true },
  lastName: { type: String, default: '', trim: true }
})

会话模型

const schema = new Mongoose.Schema({
  name: { type: String, trim: true },
  type: { type: String, required: true, enum: ['G', 'P'] },
  members: [{ type: Schema.Types.ObjectId, ref: 'Users' }]
}, { timestamps: true })

消息模型

const schema = new Mongoose.Schema({
  conversationId: { type: Schema.Types.ObjectId, ref: 'Conversations' },
  body: { type: String, trim: true },
  author: { type: Schema.Types.ObjectId, ref: 'Users' }
}, { timestamps: true })

使用此套接字连接完成聊天部分

io.on('sendMessage', async(action2) => {
    action2.author = socket.decoded.id
    action2.markRead = markReadSocket
    const createMessage = await Message.create(action2)
    const messages = await Message.aggregate([
      { "$match": { "_id": mongoose.Types.ObjectId(createMessage._id) } },
      { "$lookup": {
        "from": "users",
        "let": { "author": "$author" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$_id", "$$author" ] }}},
          { "$project": { "firstName": 1, "lastName": 1, "avatar": 1 } }
        ],
        "as": "author"
      }},
      { "$unwind": "$author" },
      { "$project": {
        "author": 1, "markRead": 1, "isDelivered": 1,
        "body": 1, "conversationId": 1,
        "isIncoming": { "$ne": [ "$author._id", mongoose.Types.ObjectId(socket.decoded.id) ] },
      }}
    ])
    io.emit(action2.conversationId, messages)
  })

上面的代码对于一对一对话和小组对话都很好。

现在我要实现的是像应用程序一样显示已交付(两个灰色)和已读(两个蓝色)的刻度。我是否需要为readBydeliveredTo分别创建集合,并需要在其中保存timeuserId

如何使用nodejssocketio执行此操作?如果有人以前这样做过,请发布您的代码,我们将设法理解它。

任何帮助将不胜感激!

提前谢谢!

3 个答案:

答案 0 :(得分:3)

在创建新的消息实体并将其发送给收件人之后,收件人应在收到此消息后立即发出新的 delivered 事件。如果打开此消息,请发送另一个带有 read 主题的事件。这两个事件都必须包含消息ID。

在服务器端,收到上述事件后,检查消息的发件人是否已收到并传递适当的事件,而不会将消息的当前状态通知发件人。

答案 1 :(得分:3)

  

客户端

伪代码

1. Register handler for 'newMessage' event, this will emit 'received' event
2. Function to emit 'markSeen' event, this will execute when the message is opened (chat window)
3. Register handler for 'delivered' event, this will display 'grey' ticks
4. Register handler for 'markedSeen' event, this will display 'blue' ticks

功能

// Handler for 'newMessage' event
socket.on('newMessage', function(message) {
    chatMessages[message.MESSAGE_ID] = message;

    var options = {
        messageID: message.MESSAGE_ID,
        timetoken: moment().valueOf()
    };

    // Emit 'received' event
    socket.emit('received', options);
});

// function to emit 'markSeen' event
function markSeen(message) {
    var options = {
        messageID: message.MESSAGE_ID
    };

    // Emit 'markSeen' event
    socket.emit('markSeen', options);
}

// Handler for 'delivered' event
socket.on('delivered', function(message) {
    chatMessages[MESSAGE_ID].delivered = true;
});

// Handler for 'markedSeen' event
socket.on('markedSeen', function(message) {
    chatMessages[MESSAGE_ID].seen = true;
});

  

服务器端

伪代码

1. Register handler for 'received' event, this will emit 'delivered' event
2. Register handler for 'markSeen' event, this will emit 'markedSeen' event

功能

// Handler for 'received' event
io.on('received', function(options) {
    var options = {
        timetoken: moment().valueOf(),
        userID: options.message.SENDER_ID,
        messageID: options.message.MESSAGE_ID
    };

    // Emit 'delivered' event
    socket.emit('delivered', options);
});

// Handler for 'markSeen' event
io.on('markSeen', function(options) {
    var options = {
        timetoken: moment().valueOf(),
        userID: options.message.SENDER_ID,
        messageID: options.message.MESSAGE_ID
    };

    // Emit 'markedSeen' event
    socket.emit('markedSeen', options);
});

答案 2 :(得分:1)

您需要跟踪2个不同的事物。服务器收到消息后。当您将其添加到数据库中时,这就是您要设置的传递滴答为true的时间。此时,您可以向发送的网络套接字发送一条消息,告诉他们消息已经传递到服务器,然后客户端发件人可以设置其灰色勾号。

类似地,在接收方,一旦接收方登录,就会转到该消息所在/打开该消息的页面。基本上,只要对他们可见,您就可以遍历当前对他们可见的所有消息,如果没有将“ hasRead”检查为true的话,则可以向控制器发送呼叫,该控制器可以将其设置为“ hasRead = true”。此时,您的websocket可以尝试更新发件人(如果他们在线)以确保已阅读邮件。如果他们不在线,那么您可以做同样的事情。例如:如果发件人在线,请在每封邮件中传递“ hasRead”属性,然后您可以相应地设置蓝色对勾。”