简体   繁体   中英

How do I use socket.io and express together?

I've got a problem with socket.io emit and express. I want to emit some data (I'm creating a webgame) so I need to emit players data to a specific lobby. For example I create a lobby at this link: localhost:8000/test/lobbyName and I need to emit information only to this lobby and no to the others. How I can do that?

this is my code:

www

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('progetto:server');
var http = require('http');
/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '8000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.Server(app);
var io = require('socket.io').listen(server);

//Game
let players = {};

let xCoin = Math.floor((Math.random() * 1200));

io.on('connection', function(socket){
  console.log('A user connected');

  players[socket.id] = {
      rotation: 0,
      x: 0,
      y: 0,
      layer: Math.floor((Math.random() * -1200)),
      playerId: socket.id,
      frame: 0,
      haveGun: true,

  };

  socket.emit('currentPlayers', players);

  socket.broadcast.emit('newPlayer', players[socket.id]);

  socket.emit('newCoin',  xCoin);

  socket.on('disconnect', function () {
      console.log('User disconnected');

      delete players[socket.id];

      io.emit('disconnect', socket.id);

  });

  socket.on('playerMovement', function (movementData) {
      players[socket.id].x = movementData.x;
      players[socket.id].y = movementData.y;
      players[socket.id].layer = movementData.layer;
      players[socket.id].frame = movementData.frame;

      socket.broadcast.emit('playerMoved', players[socket.id]);

  });

  socket.on('playerAngle', function (movementData) {
      socket.broadcast.emit('gunAngle', socket.id, movementData);

  });

  socket.on('playerShotting', function (movementData) {
      socket.broadcast.emit('shotting', socket.id, movementData);

  });

  socket.on('coinTaken', function (x, y) {
      socket.broadcast.emit('taken', x, y);

  });

  socket.on('createGun', function (n1, n2) {
      socket.broadcast.emit('enemyGun', players[socket.id].playerId, n1, n2);

  });

})





/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

main.js

let game = new Phaser.Game(
    {
        type: Phaser.AUTO,
        width: window.innerWidth,
        height: window.innerHeight,
        physics:  {
            default: 'arcade',
            arcade:   {
                debug: false,
                gravity: { y: 0 }

            }
        },
        scene: {
            preload: preload,
            create: create,
            update: update

        }
});

let playerInfo = ['Daniel', 100, 100, 3, 12, 1000];       //nickname , gold, life , jump , spead , gravity

let player =  new Player(game, playerInfo);
let background =  new Background();
let settings = new Settings();

function preload () {
    load(this);

    loading(this);

    settings.preload();
}

function create () {
    let playerArray = [0, 0];

    this.socket = io();

    player.debug(this);

    var self = this;

    this.otherPlayers = this.physics.add.group();

    this.socket.on('currentPlayers', function (players) {
        Object.keys(players).forEach(function (id) {
            if (players[id].playerId === self.socket.id) {
                player.createPlayer(self, players[id]);

            }else if(playerArray[0] == 0) {
                playerArray[0] = players[id].playerId;
                player.createEnemyOne(self, players[id]);

            }else if(playerArray[1] == 0) {
                playerArray[1] = players[id].playerId;
                player.createEnemyTwo(self, players[id]);

            }else {
                playerArray[2] = players[id].playerId;
                player.createEnemyTre(self, players[id]);

            }
        });
    });

    this.socket.on('newPlayer', function (playerInfo) {
        if(playerArray[0] == 0) {
            playerArray[0] = playerInfo.playerId;
            player.createEnemyOne(self, playerInfo);

        }else if(playerArray[1] == 0) {
            playerArray[1] = playerInfo.playerId;
            player.createEnemyTwo(self, playerInfo);

        }else {
            playerArray[2] = playerInfo.playerId;
            player.createEnemyTre(self, playerInfo);

        }
    });

    this.socket.on('disconnect', function (playerId) {
        self.otherPlayers.getChildren().forEach(function (otherPlayer) {
            if(playerId === otherPlayer.playerId) {
                otherPlayer.destroy();
            }
            for(var i = 0; i < 2; i++) {
                if(playerId == playerArray[i]) {
                    playerArray[i] = 0;

                }
            }
        });
    });

    this.socket.on('playerMoved', function (playerInfo) {
        if(playerArray[0] == playerInfo.playerId) {
            move = playerInfo.layer - background.midle.x;
            player.setPosition(player.enemy, player.gun1,player.textEn1, playerInfo.x - move, playerInfo.y * window.innerHeight, playerInfo.frame, player.haveGun1);

        }else if(playerArray[1] == playerInfo.playerId) {
            move = playerInfo.layer - background.midle.x;
            player.setPosition(player.enemy2, player.gun2, player.textEn2, playerInfo.x - move, playerInfo.y * window.innerHeight, playerInfo.frame, player.haveGun2);

        }else {
            move = playerInfo.layer - background.midle.x;
            player.setPosition(player.enemy3, player.gun3, player.textEn3, playerInfo.x - move, playerInfo.y * window.innerHeight, playerInfo.frame, player.haveGun3);

        }
    });

    this.input.on('pointermove', function (pointer) {
        if(player.haveGun) {
            let angle = (Phaser.Math.Angle.Between(player.player.x , player.player.y, pointer.x , pointer.y)) * (180/Math.PI);
            player.gun_angle(angle + 90);

        }
    });

    this.socket.on('gunAngle', function (id, playerInfo) {
        if(playerArray[0] == id) {
            if(player.haveGun1) player.gunAngle(player.gun1, playerInfo.angle);

        }else if(playerArray[1] == id) {
            if(player.haveGun2) player.gunAngle(player.gun2, playerInfo.angle);

        }else {
            if(player.haveGun3) player.gunAngle(player.gun3, playerInfo.angle);

        }
    });

    this.socket.on('shotting', function (id, playerInfo) {
        if(playerArray[0] == id) {
            player.shot(self.bulletsEnemy, player.enemy, playerInfo);

        }else if(playerArray[1] == id) {
            player.shot(self.bulletsEnemy2,player.enemy2,  playerInfo);

        }else {
            player.shot(self.bulletsEnemy3,player.enemy3,  playerInfo);

        }
      });

      this.socket.on('newCoin', function (x) {
          background.worldObject.createCoin(self, x, true);

      });

      this.socket.on('taken', function (x, y) {
          background.worldObject.coin.destroy();
          background.worldObject.createCoin(self, x, y);

      });

      this.socket.on('enemyGun', function (id, info, info2) {
        if(playerArray[0] == id) {
            player.enemyGun1(self, info, info2);
        }else if(playerArray[1] == id) {
            player.enemyGun2(self, info, info2);
        }else {
            player.enemyGun3(self, info, info2);
        }

      });

      background.createBackground(this);

      settings.create(this);

}

function loading(game) {
    let progressBar = game.add.graphics();
    let progressBox = game.add.graphics();
    let width = 320, heigth = 50;
    progressBox.fillStyle(0x222222, 0.8);
    progressBox.fillRect(window.innerWidth / 2 - (width / 2), window.innerHeight / 2 - (heigth / 2), width, heigth);

    let loadingText = game.make.text({
        x: window.innerWidth / 2,
        y: window.innerHeight / 2 - 50,
        text: 'Loading...',
        style: {
            font: '20px monospace',
            fill: '#ffffff'
        }
    });

    let percentText = game.make.text({
        x: window.innerWidth / 2,
        y: window.innerHeight / 2 - 5,
        text: '0%',
        style: {
            font: '18px monospace',
            fill: '#ffffff'
        }
    });

    let assetText = game.make.text({
        x: window.innerWidth / 2 - 100,
        y: window.innerHeight / 2 + 50,
        text: '',
        style: {
            font: '18px monospace',
            fill: '#ffffff'
        }
    });

    percentText.setOrigin(0.5, 0.5);

    loadingText.setOrigin(0.5, 0.5);

    game.load.on('progress', function (value) {
        progressBar.clear();
        progressBar.fillStyle(0xffffff, 1);
        progressBar.fillRect(window.innerWidth / 2 - ((width - 20) / 2), window.innerHeight / 2 - ((heigth - 20) / 2), 300 * value, heigth - 20);

        percentText.setText(parseInt(value * 100) + '%');

    });

    game.load.on('fileprogress', function (file) {
      console.log(file.key);
        assetText.setText('Loading asset: ' + file.key);

    });

    game.load.on('complete', function () {
        progressBar.destroy();
        progressBox.destroy();
        loadingText.destroy();
        percentText.destroy();
        assetText.destroy();

    });
}

function load(game) {

    let playerImg = ['/images/snowman.png', '/images/snowman.png', '/images/snowman.png', '/images/snowman.png'];

    let sound = ['/sounds/Jump.mp3', '/sounds/Explosion.mp3', '/sounds/Pickup_Coin.mp3']

    let groundImg = ['/images/ground.png','/images/nuvola.png', '/images/map.json', '/images/coin.png', '/images/heart.png', '/images/pozioni.png'];

    game.load.spritesheet('player', playerImg[0], { frameWidth: 128, frameHeight: 128 });
    game.load.spritesheet('enemy', playerImg[1], { frameWidth: 128, frameHeight: 128 });
    game.load.spritesheet('enemy2', playerImg[2], { frameWidth: 128, frameHeight: 128 });
    game.load.spritesheet('enemy3', playerImg[3], { frameWidth: 128, frameHeight: 128 });

    game.load.audio('jumpAudio', sound[0]);
    game.load.audio('shotAudio', sound[1]);
    game.load.audio('coinAudio', sound[2]);

    game.load.image("tiles1", groundImg[0]);
    game.load.image("tiles2", groundImg[1]);
    game.load.tilemapTiledJSON("map", groundImg[2]);

    game.load.spritesheet("coin", groundImg[3], { frameWidth: 128, frameHeight: 128 });
    game.load.spritesheet("heart", groundImg[4], { frameWidth: 128, frameHeight: 128 });
    game.load.spritesheet("pozions", groundImg[5], { frameWidth: 32, frameHeight: 32 });

}

function update () {
    if(player.life != false)  player.update(this);

    background.update(this);

    background.midle.setCollisionByProperty({colision:true});

    this.physics.add.collider(player.player, background.midle);

}

window.addEventListener('resize', function() {
    game.scale.setGameSize( window.innerWidth, window.innerHeight);

    background.midle.displayHeight = window.innerHeight;

    player.resize();

    settings.resize();

});

Then I want to let the user create their rooms, so I followed a tutorial that I found and that's the code in my index.js file:

router.get('/test/:id', function(req, res, next){
  res.render('test', {output: req.params.id} );
})

router.post('/test/submit', function(req, res, next){
  var id = req.body.id;
  res.redirect('/test/' + id);
})

and this is the the form:

<form action="/test/submit" method="post">
  <input type="text" name="id">
  <button type="submit">Submit</button>
</form>

Now, how can I use socket.io to emit players data only to the redirect page that the player is connected?

Sorry for my poor english, thank you

You should make use of socket.io rooms or namespaces .

Rooms

On socket connection, join the socket to a specific room, in your case: lobbyName for example, and then emit only to that room

io.to('lobbyName').emit(...)

Namespaces

On the backend, create one namespace per lobby.

const lobbies = ['/lobbyName'];

for(const lobby of lobbies) {
    const nsp = io.of(lobby);
    // Your socket logic in here
    nsp.on('connection', socket => {
      console.log('someone connected');
    });
}

And connect to that specific namespace in the front end:

const socket = io('/lobbyName');

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