简体   繁体   中英

Streaming data from the Server to Client with Meteor:

I'm developing a text based adventure game with Meteor and I'm running into an issue with how to handle certain elements. Namely, how to emit data from the Server to the Client without any input from the Client.

The idea is that when a player is engaged in combat with a monster, the combat damage and updating the Player and Monster objects will be occurring in a loop on the server. When the player takes damage it should accordingly update the client UI. Is something like this possible with Publish / Subscribe?

I basically want something that sits and listens for events from the server to update the combat log accordingly.

In pseudo-code, this is something along the lines of what I'm looking for:

// 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
    }
});

I understand that you can publish a collection to the client, but that's not really as specific of a function I'm looking for, I don't want to publish the entire Player object to the client, I just want to tell the client to write a line to a textbox saying something like "You were hit for 12 damage by a monster!".

I was hoping there was a function similar to SocketIO where I could, if I wanted to, just emit an event to the client telling it to update the UI. I think I can use SocketIO for this if I need to, but people seemed to be adamant that something like this was doable with Meteor entirely without SocketIO, I just don't really understand how.

The only outs I see to this scenario are: writing all of the game logic client-side which feels like a bad idea, writing all of the combat logs to a collection which seems extremely excessive (but maybe it's not?), or using some sort of SocketIO type-tool to just emit messages to the client to tell it to write a new line to the text box.

Using Meteor, create a combat log collection seem to be the simplest option you have. You can only listen on added event and then clear the collection when the combat is over. It should be something like this :

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

I ask a similar question here , hope this will help ^^

Here's how I did it without a collection. I think you are right to be concerned about creating one. That would not be a good idea. First install Streamy.

https://atmospherejs.com/yuukan/streamy

Then on the server

    //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);
        })
    }

Then in the client, respond to it like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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