首页 > 解决方案 > Node JS socket.on() 客户端故障?

问题描述

我正在学习 Node JS,遇到了一些奇怪的行为,也许有人知道答案。我遇到的很多教程帖子都说要在客户端使用“socket.on('connect', function(){ blah blah }); 向服务器发送请求。基本上这应该停止一个调用从被发送到服务器,直到服务器与客户端建立连接。但是当我测试代码时,只要先运行客户端html,然后再启动节点js,它就可以工作。如果节点js正在运行首先是服务器代码,然后是客户端html启动,由于某种原因,emit函数没有调用服务器。如果我省略socket.on函数并直接进入我的socket.emit函数,服务器会收到来自客户端的发射功能。如果 node js 没有先运行,客户端 html 会继续运行,直到 node js 启动服务器脚本,此时客户端连接,并自动发出请求。有谁知道为什么会这样?正如我所说,我仍在学习 Sockets 和 Node JS,所以我宁愿理解这种行为,而不是继续我的编码,即使我让它工作了。您提供的任何信息都将非常有价值。谢谢。:)您提供的任何信息都将非常有价值。谢谢。:)您提供的任何信息都将非常有价值。谢谢。:)

// Server side

var express = require('express');
var socket = require('socket.io');
var app = express();
var server = app.listen(1111, function(){ console.log("Server Listening"); });
var io = socket(server);

io.on('connect', function(socket) {

	socket.on('Contact', function(data) {

		socket.join(data);
		console.log(data); // just to test if data is sent
		
	});

});
// Client in head section

<script src = "https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
<script type = "text/javascript">
var socket = io.connect("http://localhost:1111");

function Setup() { // called when page has loaded

  //blah blah blah lots and lots of code
  
  var data = "blahblah"; // room to join
  
  socket.on('connect', function(){
  
    socket.emit('Contact', data);
   });
}
   
 // If I remove the socket.on function it works flawlessly everytime.  Left in, it will only fire if the
 // node js server file is launched after the client launches

标签: javascriptnode.jssockets

解决方案


似乎您Setup()稍后会手动调用该函数(可能在页面加载事件中,基于评论)。这意味着您正在创建一个竞争条件:如果服务器在页面加载事件之前连接,则连接事件发生得太快,您只能在它发生后附加您的侦听器。

所以基本上发生的事情是这样的:

第一种情况(服务器在客户端之后启动)

  • 客户端 HTML 加载,脚本执行
  • 客户端开始尝试连接到服务器
  • 客户端资产加载完毕,Setup()调用
  • 附加到套接字的客户端connect侦听器
  • 服务器启动,开始接受连接
  • 服务器接受客户端连接
  • 客户端connect侦听器触发,发出联系事件

第二种情况(客户端在服务器之后启动)

  • 服务器启动,开始接受连接
  • 客户端 HTML 加载,脚本执行
  • 服务器接受客户端连接
  • 当前没有connect侦听器,因此没有任何反应
  • 客户端资产加载完毕,Setup()调用
  • 附加到套接字的客户端connect侦听器
  • 安静...

要解决此问题,您应该只io.connect(...)在向其添加侦听器的同一范围内调用。这意味着要么移动 Setup() 的socket.on('connect', ...)外部,要么移动 Setup() 的io.connect()内部(可能更好)。


推荐阅读