Question

I'm trying to make a realtime multiplayer web-game in node.js with express framework and socket.io library. But I can't seem to make my server-side logic independent of client interactions. I want client to interact only when I (server side logic) want but I can't seem to be able to do that. For example:

I want 2 users to start playing a game. I have to first initialize the game, like set up environment, variables and stuff.. all in a separate, call it: The Game Logic. Only then can I "allow" the clients to interact.

But how am I supposed to carry on with my Game logic when my socket.on event is "calling the shots"? With socket.io you have to define triggers like

io.sockets.on('connection', function(socket) {
    socket.on('event', function(data) {
        //supposed this is fired when client hits an "interact with X" button
    }); 
}

All my logic seem to be dependent on these triggers. I only wanted client to be able to fire that event when I want (after I've set up the game env etc), but defining it like so, separated from my game logic, it creates problems like how am I supposed to transfer the execution control from socket into my game logic? And even if I managed to, there's that whole client "calling the shots" problem. I then have no control when client could want to interact.

Any advice what should I do?

Était-ce utile?

La solution

Your game object would typically be a separate prototype function (class). It might look like this:

Game = function() {
  var sockets = [];
  var pendingEvents = [];
  var interval = 500; // Process every 0.5s

  var init = function() {
    // Do game initialization stuff here

    // Start the game timer
    setInterval(function() {
      gameLoop();
    });
  };

  // Do the actual game loop
  gameLoop = function() {
     // Do some work

     // Handle user events, starting with the oldest
     var message = pendingEvents.shift();
     while ( null != message ) {
         handleMessage(message.socket, message.data);
         var message = pendingEvents.shift();
     }

     // Do other stuff
  };

  // Process a player's message event
  handleMessage = function(socket, data) {
  };

  addSocket = function(socket) {
      sockets.push(socket);
  };

  queueEvent = function(event) {
      pendingEvents.queue(event);
  };

  return {
    queueEvent: queueEvent,
    addSocket: addSocket
  };
}

This game class gives you a skeleton that holds all the connected sockets (loop through to send a message to everyone) and does some game logic every 500ms. During the game loop it looks in the message queue for player events it needs to handle.

Now going back to your original socket code, you can inject player events into the game like this:

// This happens anywhere
var gameInstance = new Game();

// Now watch for sockets
io.sockets.on('connection', function(socket) {
  // Add the socket to the game
  gameInstance.addSocket(socket);

  socket.on('event', function(data) {
    // Push the client event to the game, game will handle it on its own terms
    gameInstance.queueEvent({
      socket: socket,
      data: data
    });
  }); 
}

Autres conseils

You need to make the client available for receiving a call.

You either "push" sample/source or setup a "client-server" sample/source

Another option would be to have the client call to the server at a scheduled time (like every 15 min) and if there is something you want to "say/do" it happens then.

Licencié sous: CC-BY-SA avec attribution
scroll top