使用Node.js和MongoDB进行长时间轮询时,在获取消息时无法维护上下文

时间:2018-11-20 03:54:43

标签: javascript node.js ajax

我正在研究使用长轮询技术实现聊天功能的应用程序,其中要求db及时更新。我知道可以通过使用socket.io来完成此操作,但是我已经开始使用长轮询进行实现了,而且我在有限的时间内完成此操作。

现在,我在轮询聊天中的更新时遇到问题,并且给定聊天ID的上下文未维护。进行轮询时,即使用户处于其他聊天框中,也会检索第一个打开的聊天消息。任何解决此问题的帮助都将受到赞赏。

AJAX功能:

if(users){

    users.forEach(user => user.addEventListener('click', function(e) {

        let imageSrc = this.firstElementChild.currentSrc;
        let name = this.lastElementChild.innerText;
        let receiver = this.dataset.receiver;
        console.log(receiver);
        let sender = this.dataset.sender;
        console.log(sender);
        let countMessages = document.querySelectorAll('#chatForm span');
        let textArea = document.querySelector('.btn-send').setAttribute('data-receiver', receiver);
        swipeChat.nextElementSibling.setAttribute('src', imageSrc);
        swipeChat.parentElement.querySelector('b').innerText = name;

        setInterval(function () {
            //retreive user chat
            $.ajax({
                url: '/getMessage',
                method: 'POST',
                data : {receiver:receiver,sender:sender},
                dataType:'json',
                success: function(response){
                    let oldMessages = document.querySelectorAll('#textArea .incoming');

                    let messages = response.data;
                    let data = messages.map(message => {
                        let html = `<span class="chatMsg ${sender!=message.sender? 'incoming':'outgoing' }">${message.message}</span>`;
                        return html;
                    }).join(" ");
                    document.querySelector('#textArea').innerHTML =  data;
                    let newMessages = document.querySelectorAll('#textArea .incoming');
                    if(oldMessages.length > 0){
                        if(newMessages.length>oldMessages.length){
                            document.querySelector('#msg-new').play();
                            document.querySelector('#chatForm').scrollTop = document.querySelector('#chatForm').scrollHeight;
                        }
                    }
                }
            });
        },5000);
        }));

    }

getMessage.js

    router.post('/getMessage',function(req,res){
        Message.find(
            {$or:[
                    {sender:req.body.sender,receiver:req.body.receiver},
                    {sender:req.body.receiver,receiver:req.body.sender}
                 ]
            },
            (err,data) => {
                res.send({success:true,data:data});
            }
        );

    });

1 个答案:

答案 0 :(得分:0)

在这种情况下,长时间轮询正在切换关于聊天ID的上下文,因为先前的ajax请求仍处于活动状态。因此,单击聊天框时,“接收者”正在接收多个用户ID。为了解决这个问题,我使用了clear interval()函数,如下所示:

var ajxReq;
var interval;
if(users){

    users.forEach(user => user.addEventListener('click', function(e){
        let imageSrc = this.firstElementChild.currentSrc;
        let name = this.lastElementChild.innerText;
        let receiver = this.dataset.chatreceiver;
        console.log("receiver"+receiver);
        let sender =  this.dataset.sender;
        let countMessages  = document.querySelectorAll('#chatForm span');
        let textArea = document.querySelector('.btn-send').setAttribute('data-receiver', receiver);
        swipeChat.nextElementSibling.setAttribute('src', imageSrc);
        swipeChat.parentElement.querySelector('b').innerText = name;
        if (ajxReq != null) {
            ajxReq = null;
            clearInterval(interval);
        }
        interval = setInterval(function(){

            //retreive user chat
            ajxReq = $.ajax({
                url: '/getMessage/'+receiver,
                method: 'POST',
                data : {sender:sender},
                dataType:'json',
                success: function(response){
                    //receiver = response.receiver;
                    let oldMessages = document.querySelectorAll('#textArea .incoming');
                    let messages = response.data;
                    let data = messages.map(message => {
                        //receiver=message.receiver;
                        let html = `<span class="chatMsg ${sender!=message.sender? 'incoming':'outgoing' }">${message.message}</span>`;
                        return html;
                    }).join(" ");
                    document.querySelector('#textArea').innerHTML =  data;
                    let newMessages = document.querySelectorAll('#textArea .incoming');
                    if(oldMessages.length > 0){
                        if(newMessages.length>oldMessages.length){
                            //console.log(`RING- ${newMessages.length} ${oldMessages.length}`);
                            document.querySelector('#msg-new').play();
                            document.querySelector('#chatForm').scrollTop = document.querySelector('#chatForm').scrollHeight;
                        }
                    }
                }
            });
        },1000);

    }));

}