我正在研究使用长轮询技术实现聊天功能的应用程序,其中要求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});
}
);
});
答案 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);
}));
}