显示已交付和蓝色勾号,如 whats app

Show delivered and blue ticks like whats app

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

这是它的代码

用户模型

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)
  })

以上代码适用于一对一对话和群组对话。

现在我想要实现的是显示已发送(两个灰色)和已读(两个蓝色)滴答声,就像 what 应用程序一样。我是否需要为 readBydeliveredTo 制作单独的集合并需要在其中保存 timeuserId

如何使用 nodejssocketio 执行此操作?如果之前有人这样做过,请post你的代码我会设法理解它。

任何帮助将不胜感激!!!

提前致谢!!!

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

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

您需要跟踪 2 个不同的事物。一旦您的服务器收到消息。当你将它添加到数据库时,它是控制的,这是你要将传递的刻度设置为 true 的时候。在这一点上,您可以向发送网络套接字发送一条消息,告诉它他们的消息已经传送到服务器,然后客户端发件人可以设置他们的灰色勾号。

同样在接收方,一旦接收方登录,就会转到消息 is/opens 所在的页面。基本上只要它们对他们可见,您就可以浏览他们当前可见的所有消息,如果没有 "hasRead" 检查为真,那么您可以向可以设置它们的控制器发送调用至 "hasRead=true"。此时您的 websocket 可以尝试更新发件人(如果他们在线)消息已被阅读。如果他们不在线,那么你可以反过来做同样的事情。例如:如果发件人上线,则在每条消息中传递 "hasRead" 属性,您可以相应地设置蓝色勾号

Client Side

伪代码

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

Server Side

伪代码

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