1

socket.io を介してサーバーからクライアントに変数を渡そうとしています。MongoDB にデータを保存し、Mongoose を使用しています。目標は、クライアントからデータベースにデータを保存し、保存したばかりのドキュメントの _id をクライアントに返すことです。これが私がこれまでに持っているものです:

サーバ

client.on('savesnail', function (data) {
    console.log('save snail: ' + data.name);
    var snail = new Snail(data);
    snail.save(function (err, snail) {
        if (err) {console.log('err: ' + err)} // TODO handle the error
        var snailID = snail._id;
        console.log('saved snail ID ' + snailID);
        client.emit('setSnailID', snailID);
        var conditions = {_id: data.ownerID},
            update = {$set: {newUser: false}}

        User.update(conditions,update,function(err){});
        console.log('user updated');
    });

});

クライアント

saveSnail: function(snail) {
    // Core stats
    var data = {};
    data.ownerID = ig.game.sessionUserID;
    data.inDb = true;
    data.name = snail.name;
    // etc..

    console.log('saving snail');
    this.socket.emit("savesnail", data);
    this.socket.once('setSnailID', function(snailid) {
        snail.snailID = snailid;
        console.log('snail ID set: ' + snailid);
    }); 
}

サーバー コンソールでは、それぞれの「保存されたカタツムリ ID」は一意で正しいように表示されます。ただし、「setSnailID」に出力し、同じ変数をクライアント コンソールに出力した後、ID はすべての出力と同一であることが判明しました。

コンソール出力例

例として、_ids が 1 桁の数字であるとしましょう。現在、クライアントで saveSnail() を 4 回 (開始された 4 つのカタツムリごとに 1 回ずつ) 呼び出しています。サーバーコンソールに次のように表示されます。

saved snail ID 1
saved snail ID 2
saved snail ID 3
saved snail ID 4

...しかし、各 _id をクライアントに送信すると、クライアント コンソールに次のように表示されます。

snail ID set: 1
snail ID set: 1
snail ID set: 1
snail ID set: 1

this.socket.onceクライアントをに変更するthis.socket.onと、クライアント コンソールは各 ID の4 つのインスタンスを取得するため、出力が開始されることに注意してください。

snail ID set: 1
snail ID set: 1
snail ID set: 1
snail ID set: 1
snail ID set: 2
snail ID set: 2
snail ID set: 2
snail ID set: 2
// etc

...合計で 16 行になります - ID ごとに 4 行

私は最近 node.js をいじり始めたばかりで、ここで非常に基本的なことを誤解していると思います。MongoDb が新しい各エントリに割り当てる正しい一意の _id をクライアントに渡すにはどうすればよいですか?

4

1 に答える 1

1

Socket.io は文字列を送信するだけでなく、関数を含め、ほぼすべての JavaScript 値を送信します。データとともにコールバックを送信できます。

クライアント:

saveSnail: function(snail) {
    // Core stats
    var data = {};
    data.ownerID = ig.game.sessionUserID;
    data.inDb = true;
    data.name = snail.name;
    // etc..

    console.log('saving snail');
    this.socket.emit("savesnail", data, function (err, snailid) {
      if (err) {
        return console.error(err);
      }
      snail.snailID = snailid;
      console.log('snail ID set: ' + snailid);
    });
}

サーバ:

client.on('savesnail', function (data, cb) {
    console.log('save snail: ' + data.name);
    var snail = new Snail(data);
    snail.save(function (err, snail) {
        if (err) {return cb(err);} // Let the client handle the err
        var snailID = snail._id;
        console.log('saved snail ID ' + snailID);
        var conditions = {_id: data.ownerID},
            update = {$set: {newUser: false}}

        User.update(conditions,update,function(err){});
        console.log('user updated');
        cb(null, snailID);
    });
});
于 2013-04-25T23:05:39.193 に答える