繁体   English   中英

添加到按钮单击事件时,socket.io发射()不起作用

[英]socket.io emit() doesn't work when added to button click event

简而言之,我的网页执行以下操作:

  1. 使用socket.io建立一个套接字,并通过该套接字传入一些数据。
  2. 基于此数据,将创建表中的行。 每行包含一个按钮。
  3. 该按钮的功能是通过套接字发送一些数据。

服务器代码:

io = require('socket.io').listen(this.server);
io.of('/iot').use(onWSAuthorize);

function onWSAuthorize(socket, next) {
    socket.on('device_activate', function (msg) {
        console.log('device_activate received');
        onDeviceActivate(msg, socket)
    });
}

客户端:

var socket = io('/iot');
socket.on('device', setValue);

    function setValue(msg) {
        devArdID = msg.ardid + "_" + msg.devid;

        if (document.getElementById(devArdID) == null) {
            if (!msg.activated) { /* only put a device if it is not "Activated" */
                devArdID = msg.ardid + "_" + msg.devid;
                trDevName = '<tr id="' + devArdID + '" class="w3-hover-grey"><td>' + devTypeGetName(msg.devType) + '</td>';
                trActions = '<td><button id="' + devArdID + '_activate" class="small green">Activate</button></td></tr>'

                $("#devices").append(trDevName + trActions);
                $("#" + devArdID + "_activate").click(function() {
                    console.log('test');
                    socket.emit('device_activate', {my : 'test'});
                });
                //socket.emit('device_activate', {my : 'test'});
            }
        } else {
            /* the device already reported, structre needs to be filled in with new data */
            updateDeviceStatus(msg);
        }
    }     

现在,当我执行上述客户端代码,并且setValue()被服务器发出的传入“设备”事件触发时,该行将添加到表中-该行包含一个按钮。 当我按下按钮时,它的匿名函数被执行,并且我可以看到“ test”字符串出现在浏览器的控制台中。 但是,看起来好像socket.emit()没有执行。

我怎么知道它没有执行? 因此,当我与下面的下一个socket.emit()断开连接时(它将在setValue()执行期间执行),我可以看到它像在服务器上一样被执行,我看到onDeviceActivate()已执行,因此“ device_activate”事件为在服务器端收到。

你能告诉我我在这里可能做错了什么吗? 为什么socket.emit()在按下按钮时不起作用? 我在浏览器控制台中看不到任何异常。

您将socket.emit()放在socket.emit() .click()处理函数中。 直到稍后(如果有的话)某个页面中的对象实际被单击时,它才会被调用。

.click()处理程序(几乎与所有事件处理程序一样)是非阻塞且异步的,它们在将来会被称为不确定的时间。

如果客户端收到多个device消息,则此代码还存在另一个潜在问题,那么每次您收到一条device消息时,您都会添加另一个.click()处理函数,以便当实际单击该项目时,您可能会获得多个单击处理程序。在同一事件上触发。 那几乎永远不是您想要的。

如果您已在问题中更详细地说明了您实际上要尝试编写的总体问题,我们可能会建议一种更好的方法来构造没有此问题的代码。


您的代码还使用了许多未声明的变量。 这是Java语言中的一个非常糟糕的禁忌。 实际上,如果您在严格模式下运行代码(这确实应该这样做),那么这甚至将是一个错误,因为它是邪恶的。 当您分配给未声明的变量(例如devArdID ,它将成为隐式全局变量。 这意味着对同一函数的多次调用可以轻松覆盖先前调用所使用的变量。 您永远不要这样做。

还声明与varletconst一起使用的每个变量,并在可以使用的最接近范围内声明它(通常在使用它的函数或块中)。


因为您在服务器端使用.use() ,所以它是中间件。 您必须在处理后调用next()才能继续连接。 如果您不调用next() ,则连接实际上不会正确进行。

io = require('socket.io').listen(this.server);
io.of('/iot').use(onWSAuthorize);

function onWSAuthorize(socket, next) {
    socket.on('device_activate', function (msg) {
        console.log('device_activate received');
        onDeviceActivate(msg, socket)
    });
    // let middleware proceed
    next();
}

我不太确定为什么您不以更传统的方式执行此操作,因为似乎没有任何理由使用中间件:

io.of('/iot').on('connect', (socket) => {
    socket.on('device_activate', function (msg) {
        console.log('device_activate received');
        onDeviceActivate(msg, socket)
    });
});

暂无
暂无

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

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