Nodejs WebSocket:同一页面内有的Socket能收到,有的就不行?
Nodejs WebSocket:同一页面内有的Socket能收到,有的就不行?
新手,做了一个很酱油的登录页面。 点击按钮,通过SOCKET向服务器发送信号,服务器验证信号后,会把帐号密码发给登录页面用于比对。 问题出现:通过CMD提供的信息,服务器已经把信息发出去了,可是页面上收不到。 iosocket.on(‘connect’),这个是有效的,因为每次连上服务器,页面会显示“连接” iosocket.on(‘dengluzh’)和iosocket.on(‘denglumm’),这两个收不到服务器发出的信息,因为预设的几个标记都没显示,如“ZH中断”; 我感觉自己的写法没问题,因为这个页面的代码,是我从同一应用下另一个页面上面直接搬过来的,只是换了“信道”罢了。而且那个页面完全正常,Dreamweaver也没报错,运行时服务器也没报错,就是收不到。 现在有点怀疑,会不会是iosocket.on(‘信道’),同一时间能支持的信道数量有限? 自己用同一种方法做出两种结果,相当无语,求帮助 下面是页面对应部分代码:
var iosocket = io.connect();
var zh = 'ceshizhuanyongkouling-zhanghao' ;
var mm = 'ceshizhuanyongkouling-mima';
iosocket.on('connect',function(){
$('#zhuangtai').append('<li>连接</li>');
iosocket.on('dengluzh', function(dengluzh) {
$('#zhuangtai').append($('<li></li>').text(dengluzh));
zh = dengluzh;
$('#zhuangtai').append('<li>ZH中断</li>');
});
iosocket.on('denglumm', function(denglumm) {
$('#zhuangtai').append($('<li></li>').text(denglumm));
mm = denglumm;
$('#zhuangtai').append('<li>MM中断</li>');
if((($('#username').val())==(zh))&&(($('#password').val())==(mm))){
$('#zhuangtai').append('<li>登录成功</li>');
alert("登录成功");
window.location="jieshou.html";
}else{$('#zhuangtai').append('<li>已停止工作</li>');}
下面是服务器端对应部分代码:
else if(jsmsg == 'ceshizhuanyongkouling-denglu'){
console.log('收到信号:',jsmsg);
.........访问数据库并取得帐号密码...........
for(var i=0; i<results.length; i++){
var firstResult = results[i];
console.log('id: ' + firstResult['id']+' username: ' + firstResult['username']);
msgzh = firstResult['username'];
socket.broadcast.emit('dengluzh',msgzh);
msgmm = firstResult['password'];
socket.broadcast.emit('denglumm',msgmm);
console.log('发送数据:', msgzh,msgmm);
}
针对你遇到的问题,我将尝试提供一些可能的原因和解决方案。
可能原因
- 多个
socket
实例:你在页面中可能创建了多个socket
实例,导致某些事件监听器没有正确绑定到正确的socket
实例。 - 事件覆盖:可能你在多次加载页面时,重复绑定了事件监听器,导致某些事件被覆盖。
- 网络问题或服务器配置:服务器可能没有正确配置广播消息到客户端,或者网络问题导致消息未能到达客户端。
解决方案
1. 确保只有一个 socket
实例
确保在页面中只创建一个 socket
实例,并且所有的事件监听器都绑定到这个实例上。
var iosocket = io.connect();
iosocket.on('connect', function() {
$('#zhuangtai').append('<li>连接</li>');
// 移除重复的事件监听器
iosocket.off('dengluzh');
iosocket.off('denglumm');
iosocket.on('dengluzh', function(dengluzh) {
$('#zhuangtai').append($('<li></li>').text(dengluzh));
$('#zhuangtai').append('<li>ZH中断</li>');
});
iosocket.on('denglumm', function(denglumm) {
$('#zhuangtai').append($('<li></li>').text(denglumm));
$('#zhuangtai').append('<li>MM中断</li>');
if (($('#username').val()) == (dengluzh) && ($('#password').val()) == (denglumm)) {
$('#zhuangtai').append('<li>登录成功</li>');
alert("登录成功");
window.location = "jieshou.html";
} else {
$('#zhuangtai').append('<li>已停止工作</li>');
}
});
});
2. 检查服务器配置
确保服务器端正确配置了广播消息。你的服务器端代码看起来基本正确,但需要确认是否所有客户端都能接收到这些广播消息。
else if (jsmsg == 'ceshizhuanyongkouling-denglu') {
console.log('收到信号:', jsmsg);
// 访问数据库并取得帐号密码
for (var i = 0; i < results.length; i++) {
var firstResult = results[i];
console.log('id: ' + firstResult['id'] + ' username: ' + firstResult['username']);
var msgzh = firstResult['username'];
var msgmm = firstResult['password'];
// 广播消息到所有客户端
socket.broadcast.emit('dengluzh', msgzh);
socket.broadcast.emit('denglumm', msgmm);
console.log('发送数据:', msgzh, msgmm);
}
}
总结
通过以上步骤,你应该能够解决页面上不同 socket
实例之间消息接收不一致的问题。确保只创建一个 socket
实例,并且正确绑定事件监听器。同时检查服务器端配置,确保消息能够正确广播到所有客户端。
你把iosocket.on('dengluzh', function(dengluzh) {});
这些监听的事件不要写到iosocket.on('connect',function(){});
这里面试试。
记得 broadcast
有个坑是不会发给自己的, 不知道是不是相关
在这一点上,已经颠来倒去折腾好几回了。。你说的我刚才又试了一遍。。没有效果。。
遇到过这种情况,不过我是服务器端发送,页面接收,应该没有这个问题的。。 主要纠结就是同样的结构,另外一个页面运行正常,这个就无效,还没有报错,就是出不来。。
为什么要把单个用户的帐号密码广播(broadcast)出去?难道用户A要登录,还要先知会用户B/C/D等?就不能正常的socket.emit(‘dengluzh’,msgzh)吗,或者说有非常特殊的需求? 客户端是copy另外一个页面,服务器端的代码也是直接copy过来的?如果是你自己重新写的,那出错有什么好奇怪的。
牛人。。见效了。。 怎么说呢。。我只是想做一个打酱油的登陆界面,能验证数据库里的惟一一个帐号就好。。 至于广播,是因为我找的资料(主要借鉴一个实时聊天程序),里面用的都是broadcast,所以以为是定死了的。。多谢你教我这个。。 关于程序,是我自己东拼西凑捏起来的。。 这次是我第一次用Javascript/Nodejs/Dreamweaver/MySQL/Navicat/TeeChart。。。 再次感谢
根据你提供的代码片段,有几个可能的原因导致某些Socket事件无法触发:
-
事件绑定时机:确保
iosocket.on('dengluzh')
和iosocket.on('denglumm')
这些事件监听器是在socket连接成功之后绑定的。否则,如果在socket尚未连接时就尝试绑定这些事件,它们将不会生效。 -
作用域问题:你的事件监听器是在
iosocket.on('connect', function() { ... })
内部定义的。这会导致这些事件监听器仅在connect
事件触发后才被注册。如果你的socket连接断开后重新连接,需要重新绑定这些事件监听器。 -
多个Socket实例:检查是否在同一个页面中存在多个
io.connect()
调用,从而创建了多个Socket实例。如果确实如此,你需要确保你操作的是正确的Socket实例。
示例代码修正如下:
var iosocket = io.connect();
// 确保事件监听器是在socket连接成功之后绑定的
iosocket.on('connect', function() {
$('#zhuangtai').append('<li>连接</li>');
// 在这里绑定事件监听器
iosocket.on('dengluzh', function(dengluzh) {
$('#zhuangtai').append($('<li></li>').text(dengluzh));
$('#zhuangtai').append('<li>ZH中断</li>');
});
iosocket.on('denglumm', function(denglumm) {
$('#zhuangtai').append($('<li></li>').text(denglumm));
$('#zhuangtai').append('<li>MM中断</li>');
if (($('#username').val()) === (zh)) && ($('#password').val()) === (mm)) {
$('#zhuangtai').append('<li>登录成功</li>');
alert("登录成功");
window.location = "jieshou.html";
} else {
$('#zhuangtai').append('<li>已停止工作</li>');
}
});
});
// 如果socket连接断开后需要重新绑定事件监听器
iosocket.on('disconnect', function() {
// 可以在这里重新绑定事件监听器
});
确保你的服务器代码正确地广播了消息。如果你使用的是Socket.IO,确认服务器端正确地使用了socket.broadcast.emit
来广播消息。