【问题标题】:Node.js long polling event loop breaks the whole codeNode.js 长轮询事件循环破坏了整个代码
【发布时间】:2017-05-03 18:50:38
【问题描述】:

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

这就是我所做的:

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 代码中设置了一个循环,它会破坏整个页面,并且无法再打开对话......如果有人可以帮助我改进我的代码并设置一个简单的无技术来获取消息而不刷新页面太好了!

对不起我的英语不好!非常感谢您为我们服务!

【问题讨论】:

    标签: ajax node.js html long-polling


    【解决方案1】:

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

    您可以将 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); });
    

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

    有关详细信息,另请参阅其他相关问题:

    【讨论】:

    • 编程新手 是的,这是我的第二个网站,第一次使用 nodejs 我大约 3 个月前开始使用 ruby​​ on rails ... 非常感谢,我现在正在玩套接字 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 2017-09-30
    相关资源
    最近更新 更多