简体   繁体   English

JavaScript | Node.js将服务器端对象发送到客户端

[英]JavaScript | Node.js send serverside object to client side

I'm currently trying to send a socket.io packet from the server to the client source code. 我目前正在尝试从服务器向客户端源代码发送一个socket.io数据包。

My problem: 我的问题:

If I code both without socket.io then it would work like the following: https://jsfiddle.net/v68sd1t3/ 如果我都在没有socket.io情况下进行编码,则它将如下所示工作: https : //jsfiddle.net/v68sd1t3/

But how could i save the data packet from: 但是我怎么能保存以下数据包:

socket.on('init', function(data)

into an array to use it client side when I receive the init packet? 当我收到init数据包时,将其放入一个数组以在客户端使用它?

I've been trying to add it to a array. 我一直在尝试将其添加到数组中。 But it wouln't let me access the values outside of the socket.on function. 但这不会让我访问socket.on函数之外的值。

What I have tried: 我试过的

var socket = io();
window.game = {};

socket.on('init', function(data)
{
    window.game = data;
});

console.log(game);

Which would return a blank object. 这将返回一个空白对象。 What am I doing wrong? 我究竟做错了什么?

My Client code: 我的客户代码:

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script type="text/javascript">
    var socket = io();

    socket.on('init', function(data)
    {
        console.log(data);
    });

</script>

My Server code: 我的服务器代码:

var express = require('express');
var app = express();
var serv = require('http').Server(app);

app.get('/', function(req, res)
{
res.sendFile(__dirname + '/client/index.html');
});

app.use('/client', express.static(__dirname + '/client'));

serv.listen(2000);
console.log('Server started.');

// Modules start

var config = function() 
{
    var self = this;
    self.updateRate = 1000 / 60;
    self.roomWidth = 1920;
    self.roomHeight = 1080;
    self.playerSpeed = 4;
};

var data = function() 
{
    var self = this;
    self.loopLast = Date.now();
    self.loopNow = Date.now();
    self.loopDelta = 1;
    self.players = [];
};

var utilitys = function() 
{
    var self = this;

    self.direction = function(x1, y1, x2, y2)
    {
        return Math.atan2(y1 - y2, x1 - x2);
    };

    self.distance = function(x1, y1, x2, y2)
    {
        return Math.sqrt((x2 -= x1) * x2 + (y2 -= y1) * y2);
    };

    self.nextId = function(array)
    {
        for (var i = 0, length = array.length; i < length; i++)
        {
            if (!self.findBy(array, 'id', i + 1))
            {
                return i + 1;
            }
        }

        return array.length + 1;
    };
};

var mechanics = function(config, data, utilitys)
{
    var self = this;

    self.updateDelta = function()
    {
        data.loopNow = Date.now();
        data.loopDelta = (data.loopNow - data.loopLast) / config.updateRate;
        data.loopLast = data.loopNow;
    };

    self.updatePlayers = function()
    {
        for (var i = 0; i < data.players.length; i++)
        {
            data.players[i].update(i);
        }
    };

    self.gameLoop = function()
    {
        self.updateDelta();
        self.updatePlayers();
    };

    self.player = function(x, y)
    {
        this.id = utilitys.nextId(data.players);
        this.spawned = data.loopNow;
        this.x = x;
        this.y = y;
        this.targetX = x;
        this.targetY = y;
        this.pendingDelete = false;

        this.updateLocation = function()
        {
            if (utilitys.distance(this.x, this.y, this.targetX, this.targetY) > 20)
            {
                var direction = utilitys.direction(this.targetX, this.targetY, this.x, this.y);
                this.x += Math.cos(direction) * (config.playerSpeed * data.loopDelta);
                this.y += Math.sin(direction) * (config.playerSpeed * data.loopDelta);
            }
        };

        this.update = function(index)
        {
            this.updateLocation();

            if (this.pendingDelete)
            {
                data.players.splice(index, 1);
            }
        };
    };
};

// Modules end

// Game init start

var game = {};
game.config = new config();
game.data = new data();
game.utilitys = new utilitys();
game.mechanics = new mechanics(game.config, game.data, game.utilitys);
setInterval(game.mechanics.gameLoop, game.config.updateRate);

// Game init end

// Socket start

var io = require('socket.io')(serv, {});
io.sockets.on('connection', function(socket)
{
    game.data.players.push(new game.mechanics.player(game.config.roomWidth / 2, game.config.roomHeight / 2));
    socket.emit('init', game);
});

// Socket end

Solution

Try it like that: 像这样尝试:

socket.on('init', function(data){
    window.game = data;

    // update your game or call update method right HERE! 
    console.log(game);
});

Your Mistake 你的错误

Your problem was, that you were trying to access empty object that not been updated yet: 您的问题是,您正在尝试访问尚未更新的空对象:

// that is just creates subscribe function
// you created listener, but it does not mean that event actual happened
socket.on('init', function(data)
{
    window.game = data;
});

// now you are trying to access data, that is not updated yet
console.log(game);

Actual event will appear later, and you can access this game object only after function(data) fired by socket. 实际事件将稍后出现,并且只有在套接字触发了function(data)之后,您才能访问该game对象。

PS As javascript is asynchronous init event listener won't be fired before all your sync expressions being processed by event loop (till console.log in our case) . PS由于JavaScript是异步init事件监听器不会将您的所有同步表达式被(直到 事件循环处理前被解雇console.log在我们的例子)。 Only after that, whenever socket event would happen init listener can be fired. 只有在那之后,每当套接字事件发生时,都可以触发init监听器。


My Suggestion 我的建议

I suggest you to subscribe on events with game methods. 我建议您通过游戏方法订阅事件。 Some abstract game structure: 一些抽象的游戏结构:

class Game{
    constructor(config, socket){
       super.apply(this, arguments);
       // subscribe to startup events
       // game will start automatically after init event comes
       socket.on('init', this.init);
       // save for future ;)
       this.socket = socket;
       this.config = config;
    }
    init(data){
        // subscribe to real time events
        this.socket.on('update', this.update);
        window.requestAnimationFrame(this.tick, this.config.updateRate);
        window.addEventListener('mousedown', this.onMouseDown, false);
        window.addEventListener('resize',    this.onResize,    false);

        //some stuff
        this.update(data);
    }
    tick(){
        // recalculate some stuff each frame, then redraw
        this.draw()
    }
    draw(){
      //draw
    }
    update(data){
        console.log(data);
    }
    onMouseDown(){}
    onResize(){}
}

var game = new Game(config, socket);

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

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