使用 Meteor 将数据从服务器流式传输到客户端:

Streaming data from the Server to Client with Meteor:

我正在使用 Meteor 开发一款基于文本的冒险游戏,我 运行 遇到了如何处理某些元素的问题。即,如何在没有来自客户端的任何输入的情况下将数据从服务器发送到客户端。

这个想法是,当玩家与怪物进行战斗时,战斗伤害和更新玩家和怪物对象将在服务器上循环发生。当玩家受到伤害时,它应该相应地更新客户端 UI。发布/订阅可以实现这样的功能吗?

我基本上想要一些东西来监听来自服务器的事件以相应地更新战斗日志。

在伪代码中,这符合我正在寻找的内容:

// Client Side:
Meteor.call("runCommand", "attack monster");

// Server Side
Meteor.methods({
    runCommand: function(input) {
        // Take input, run the loop to begin combat, 
        // whenever the user takes damage update the 
        // client UI and output a line saying how much 
        // damage the player just received and by who
    }
});

我知道您可以向客户端发布一个集合,但这并不是我正在寻找的函数的具体细节,我不想向客户端发布整个 Player 对象,我只想告诉客户在文本框中写一行,说 "You were hit for 12 damage by a monster!".

我希望有一个类似于 SocketIO 的功能,如果我愿意的话,我可以向客户端发出一个事件,告诉它更新 UI。我想如果需要的话,我可以使用 SocketIO,但是人们似乎坚持认为这样的事情完全可以在没有 SocketIO 的情况下使用 Meteor,我只是不太明白怎么做。

我对这种情况的唯一看法是:在客户端编写所有游戏逻辑,这感觉是个坏主意,将所有战斗日志写入一个集合,这似乎非常过分(但也许不是? ),或使用某种 SocketIO 类型工具向客户端发送消息,告诉它在文本框中写入新行。

使用 Meteor,创建战斗日志 collection 似乎是最简单的选择。 您只能监听 added 事件,然后在战斗结束后清除 collection。 它应该是这样的:

var cursor = Combat_Log.find();
var handleCombatLog = cursor.observe({
  added: function (tmp)
  {
    // do your stuff
  }
});

我问了一个类似的问题here,希望对你有帮助^^

下面是我在没有集合的情况下是如何做到的。我认为您关心创建一个是正确的。那不是一个好主意。首先安装Streamy。

https://atmospherejs.com/yuukan/streamy

然后在服务器上

    //find active sockets for the user by id
    var sockets = Streamy.socketsForUsers(USER_ID_HERE)._sockets
    if (!Array.isArray(sockets) || !sockets.length) {
        //user is not logged in
    } else {
        //send event to all open browser windows for the user
        sockets.forEach((socket) => {
            Streamy.emit('ddpEvent', { yourKey:yourValue }, socket);
        })
    }

然后在客户端,这样回复:

Streamy.on('ddpEvent', function(data) {
    console.log("data is ", data); //prints out {yourKey:yourValue}
});