繁体   English   中英

Node.js长轮询事件循环破坏了整个代码

[英]Node.js long polling event loop breaks the whole code

我是编程的新手,在开发网站的这个阶段,我需要设置一个简单的长轮询请求,以从数据库中获取最新消息,然后将其显示给客户端。 我昨天创建了一个消息传递系统,现在它保存消息以及消息和用户之间的所有必要关系...

这是我所做的:

 var express = require('express'); var router = express.Router(); var Conversation = require('../models/conversation'); var Promise = require('promise'); // Get Homepage router.get('/', function(req, res){ res.render('index'); }); var messages = []; router.get('/inbox', function(req, res){ var promise = new Promise(function (resolve, reject) { req.user.conversations.forEach(function(id){ Conversation.getConversationById(id, function(err, conv){ if (conv){ messages.push(conv); if(messages.length == req.user.conversations.length){ resolve(messages); messages = []; } } else { console.log(err); } }); }); }).then(function(object){ res.render('inbox', {convers: object}); }).catch(function(err){ console.log(err); }); }); // Add new messages to messagesArray -> mesgArray to display them var mesgArray = []; var userIdFor = ""; router.post('/messages', function(req, res){ var convId = req.body.conversationId; userIdFor = req.user.id; var promise = new Promise(function(resolve, reject){ Conversation.getConversationById(convId, function(err, conver){ if (err){ console.log(err); } else { conver.messages.forEach(function(messa){ mesgArray.push({msg: messa.msg, owner: messa.msgOwner, ownerName: messa.msgOwnerName}); if(mesgArray.length == conver.messages.length){ resolve(mesgArray); } }); } }); }).then(function(object){ res.send({allMessages: object, userId: userIdFor}); mesgArray = []; userIdFor = ""; }).catch(function(err){ console.log(err); }); }); // Save posted message to existent conversation router.post('/saveMsg', function(req, res){ var conversationId = req.body.conversationId; var messageToSave = req.body.message; console.log(messageToSave); console.log(conversationId); Conversation.getConversationById(conversationId, function(err, conversation){ if (err){ console.log(err); } else { Conversation.getConversationById(conversationId, function(err, conversation){ if(err){ console.log(err) } else { conversation.messages.push({ msg: messageToSave, msgOwner: req.user.id, msgOwnerName: req.user.firstName }); conversation.save(function(err){ if(err){ console.log(err); } }) } }); } }); }); module.exports = router; 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script> <!-- REPLAY MESSAGE BOX --> <div class="contact-form-container hidden-mode"> <div class="row hide-contact text-right"> <img src="/images/close.png"> </div> <form> <div class="inbox-all-messages-container"> <div class="row inbox-all-messages"> <!-- Here will be all the messages --> </div> <div class="row text-center inbox-send-input"> <div class="col-lg-11 col-md-11 col-sm-11"> <textarea class="inbox-message-response-txt" placeholder="Type your message here"></textarea> </div> <div class="col-lg-1 col-md-1 col-sm-1 text-center inbox-message-send-btn"> <p class="inbox-message-send-msg-btn">Send</p> </div> </div> </div> </form> </div> <script> $(document).ready(function(){ var convId = ""; $('.inbox-messager').on('click', function(){ $('.inbox-all-messages').empty(); var conversationId = this.getAttribute("data-conv-id"); convId = conversationId; $.ajax({ url: '/messages', method: 'POST', contentType: 'application/json', data: JSON.stringify({conversationId: conversationId}), success: function(response){ response.allMessages.forEach(function(message){ if(message.owner == response.userId){ $('.inbox-all-messages').append( '<div class="row inbox-message-structure-meNot">'+ '<div class="row inbox-message-header">'+ '<div class="inbox-message-ava col-lg-1 col-md-1 col-sm-1">'+ '<img src="/images/avatar.jpg" class="inbox-message-header-ava-img">'+ '</div>'+ '<div class="inbox-message-header-senderName col-lg-3 col-md-3 col-sm-3">'+ '<p>' + message.ownerName + '</p>'+ '</div>'+ '<div class="col-lg-3 col-lg-offset-5 col-md-3 col-md-offset-5 col-sm-3 col-sm-offset-5 inbox-message-header-sentTime text-right">'+ '<p>24/05/2016</p>'+ '</div>'+ '</div>'+ '<div class="row inbox-message-body">'+ '<div class="col-lg-9 col-lg-offset-1 col-md-9 col-md-offset-1 col-sm-9 col-sm-offset-1 text-left">'+ '<p>' + message.msg + '</p>'+ '</div>'+ '</div>'+ '</div>' ); } else { $('.inbox-all-messages').append( '<div class="row inbox-message-structure-me">'+ '<div class="row inbox-message-header">'+ '<div class="inbox-message-ava col-lg-1 col-md-1 col-sm-1">'+ '<img src="/images/client.jpg" class="inbox-message-header-ava-img">'+ '</div>'+ '<div class="inbox-message-header-senderName col-lg-3 col-md-3 col-sm-3">'+ '<p>' + message.ownerName + '</p>'+ '</div>'+ '<div class="col-lg-3 col-lg-offset-5 col-md-3 col-md-offset-5 col-sm-3 col-sm-offset-5 inbox-message-header-sentTime text-right">'+ '<p>24/05/2016</p>'+ '</div>'+ '</div>'+ '<div class="row inbox-message-body">'+ '<div class="col-lg-9 col-lg-offset-1 col-md-9 col-md-offset-1 col-sm-9 col-sm-offset-1 text-left tester">'+ '<p>' + message.msg + '</p>'+ '</div>'+ '</div>'+ '</div>' ); } }); $('.inbox-all-messages').append('<div id="bottom"></div>'); $('.inbox-all-messages').scrollTo('#bottom', 100, "max"); } }); $('.contact-form-container').removeClass('hidden-mode'); $('.messenger-contaner').addClass('stop-scroll'); }); $('.hide-contact').on('click', function(){ $('.contact-form-container').addClass('hidden-mode'); $('.messenger-contaner').removeClass('stop-scroll'); }); $('.inbox-message-send-msg-btn').on('click', function(){ var messageToSend = $('.inbox-message-response-txt').val(); $.ajax({ url: '/saveMsg', method: 'POST', contentType: 'application/json', data: JSON.stringify({message: messageToSend, conversationId: convId}), success: function(response){ alert('le message a bien ete enregistree'); } }); }); }) </script> 

现在,我可以发送消息并将其存储在mongoDB中,但是我需要刷新页面以获取新消息...因此,我试图设置一个较长的轮询请求,但是找不到解决方案,因为每次我设置一个在我的jQuery代码中循环播放会破坏整个页面,并且无法再打开对话了……如果有人可以帮助我改善我的代码并建立一种简单的无技术来获取消息而不刷新页面,那将是如此美妙!

对不起,我的英语不好! 非常感谢您为我们而努力!

如果您像所说的那样完全不熟悉编程,那么与其尝试从头开始创建遇到麻烦的功能,不如使用一个可行的解决方案会是一个更好的主意。

您可以使用Socket.io进行此类操作。 它使用长时间轮询,并尝试升级到WebSocket(如果支持)。 使用非常简单。 这是服务器向客户端发送请求的完整工作示例:

var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));

这是客户端上的整个JavaScript代码:

var l = document.getElementById('l');
var log = function (m) {
    var i = document.createElement('li');
    i.innerText = new Date().toISOString()+' '+m;
    l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });

有关更多示例和更好的解释,请参阅我在GitHub上创建的项目,以演示向客户端发送消息的用法。

另请参阅其他相关问题以获取更多详细信息:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM