【问题标题】:Socket IO Client receiving object DIFFERENT from what Server sentSocket IO 客户端接收对象与服务器发送的对象不同
【发布时间】:2017-07-14 15:27:20
【问题描述】:

我正在从服务器端向客户端发送一个对象,而客户端获取的对象与我发送的对象完全不同。这就是我的意思:


代码

服务器端代码:

//Basic setup for the example
var res={};
res.models=[];
res.models[0]={};

//The OLD (wrong) value
res.models[0]['id']="b4fd12f1-61ca-4445-b916-62617f1c0a78";

//The NEW (correct) value
res.models[0]['id']="fb8f83e2-e157-4e1e-8315-8e5f03b44691";

//Output what the id is, this is always the correct id!
console.log("res.models[0]['id']: ",res.models[0]['id']);
socket.emit("updateRealSeatSelect", res);

客户端代码:

socket.on("updateRealSeatSelect", function(data){
    //Output the id when we get the object. This is always wrong!
    console.log("res.models[0]['id']: "+data.models[0]['id']);
});

输出就是问题所在。这是我得到的:


输出

服务器端输出:(正确)

res.models[0]['id']:  fb8f83e2-e157-4e1e-8315-8e5f03b44691

客户端输出:(错误!为什么不一样??)

res.models[0]['id']: b4fd12f1-61ca-4445-b916-62617f1c0a78

我有双重三重四重检查服务器正在发送正确的对象与正确的ID。 客户端拿到对象时,对象不一样,id错了!怎么会这样?


杂项

尝试:

  • 我尝试将res 复制到一个新对象中,然后发送它,但这也没有用。像这样:

    var newres = res;
    socket.emit("updateRealSeatSelect", newres);
    
  • 我也尝试在发送对象时使用JSON.parseJSON.stringify,但这也无济于事。像这样:

    socket.emit("updateRealSeatSelect", JSON.stringify(res));
    

版本:

  • Express 版本:3.5.2
  • 节点版本:v6.5.0
  • Socket.IO:v1.3.6

【问题讨论】:

  • 如果没有分配错误的值会怎样?
  • @PM77-1 首先设置错误的值是为了表明socket io正在发送旧对象。在我的实际代码中,id 设置在其他地方,然后我替换该 id 并发送消息。所以我不能跳过那一步:(但是当我在服务器端输出对象时,它是正确的。我不知道为什么它在服务器端是正确的,而在客户端是错误的。
  • 我没有提出任何建议。我只是想知道没有事先分配会发生什么。你能查一下吗?
  • 我不能跳过这一步。跳过初始生成步骤会导致应用程序跳过所有步骤。
  • 原始代码中的 id 是否设置为异步?

标签: javascript node.js sockets express socket.io


【解决方案1】:

这是我认为真正发生的事情,即使它没有在您的代码示例中演示。

您的对象的 ID 看起来像 UUID,可能暗示 Cassandra。即使它不是 Cassandra,它也可能是某个数据库,因此该对象是异步检索的,但是您在实际检索到对象之前返回响应,并且您还将对象保存在全局变量中或在调用之间共享的外部范围中socket.emit().

我还希望在您重新启动服务器后第一个 socket.emit() 根本不返回任何对象,并且所有后续响应都会获得前一个。

所以这不是这样的:

//The OLD (wrong) value
res.models[0]['id']="b4fd12f1-61ca-4445-b916-62617f1c0a78";

//The NEW (correct) value
res.models[0]['id']="fb8f83e2-e157-4e1e-8315-8e5f03b44691";

socket.emit("updateRealSeatSelect", res);

但更像这样:

database.getObject(function (data, res) {
    if (err) {
        // handle error
    } else {
        res = data;
    }
});
socket.emit("updateRealSeatSelect", res);

粗略地说。当然,这只是推测,因为您没有提供让我们重现问题的示例,并且您也没有解释代码中最相关的部分。

如果您使用回调或承诺异步获取数据,请确保在实际拥有数据之前不要尝试将其发送到套接字。

另外,请始终使用:

'use strict';

在代码的开头确保您没有隐式声明全局变量。

并了解 JavaScript 中的并发性 - 回调、延续传递样式、承诺、异步函数。

使用异步函数可能比传统的回调和 Promise 处理更幸运,所以不要使用回调:

getFromDatabase(function (err, data) {
    if (err) {
        // handle error
    } else {
        socket.emit('data', data);
    }
});

或类似的使用承诺:

getFromDatabase().then(function (data) {
    socket.emit('data', data);
}).catch(function (err) {
    // handle error
});

你会写这样的:

try {
    socket.emit('data', await getFromDatabase());
} catch (err) {
    // handle error
}

这可能更清楚地遵循控制流。

【讨论】:

  • 感谢所有提示!我想我现在可以让它工作了:)
猜你喜欢
  • 2014-08-20
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多