Multiplayer websockets problem

hello everyone

I am facing some problem in multiplayer server side code . I am using websockets for the same .

Problem

  1. new players are creating every tim
const WebSocket = require('ws')

// create new websocket server

const wss = new WebSocket.Server({port: 8000})

// empty object to store all players

var players = {}

// add general WebSocket error handler

wss.on('error', function error (error) {

  console.error('WebSocket error', error)

})

// on new client connect

wss.on('connection', function connection (client) {

  console.log('new client connected')

  // on new message recieved

  client.on('message', function incoming (data) {

    // get data from string

    var [udid, x, y, z] = data.toString().split('\t')

    // store data to players object

    players[udid] = {

      position: {

        x: parseFloat(x),

        y: parseFloat(y) + 1,

        z: parseFloat(z)

      },

      timestamp: Date.now()

    }

    // save player udid to the client

    client.udid = udid

    console.log(udid);

  })

})

function broadcastUpdate () {

  // broadcast messages to all clients

  wss.clients.forEach(function each (client) {

    // filter disconnected clients

    if (client.readyState !== WebSocket.OPEN) return

    // filter out current player by client.udid

    var otherPlayers = Object.keys(players).filter(udid => udid !== client.udid)

    // create array from the rest

    var otherPlayersPositions = otherPlayers.map(udid => players[udid])

    // send it

    client.send(JSON.stringify({players: otherPlayersPositions}))

  })

 

}

// call broadcastUpdate every 0.1s

setInterval(broadcastUpdate, 20000)

please provide any optimal solution

What’s the issue exactly ? Do you have an error or something ?

When it comes to the optimal solution, you are broadcasting the position of your players every 20 seconds (not 0.1s as your comment says). Besides, even if you sent the data every 0.1s I don’t think that’s the best idea.

I think you would be better off calling broadcastUpdate everytime your receive your “message” event. otherwise you send data to players even when no one moves.

you could also use socket.broadcast (Broadcasting events | Socket.IO) to emit your message to everyone except the sender

1 Like

Exacty . Thanks for the solution any script sample for this problem because i am using websocket instead of socket.io . Any way thanks for the solution …

Can you share the multiplayer related code you use on PlayCanvas so I can test please ?

1 Like

Okay so for the backend :

const WebSocket = require('ws')
// create new websocket server
const wss = new WebSocket.Server({port: 8000})
// empty object to store all players
var players = {}
// add general WebSocket error handler
wss.on('error', function error (error) {
  console.error('WebSocket error', error)
})

// on new client connect
wss.on('connection', function connection (client) {
  console.log('new client connected')
  // on new message recieved
  client.on('message', function incoming (data) {
    // get data from string
    const message =  JSON.parse(data.toString());
    const body = JSON.parse(message.text);
    var {udid, x, y, z} = body
    // store data to players object
    players[udid] = {
      position: {
        x: parseFloat(x),
        y: parseFloat(y) + 1,
        z: parseFloat(z)
      },
      timestamp: Date.now()
    }
    // save player udid to the client
    client.udid = udid;
    // send position data to other players
    broadcastUpdate();
  })
})

function broadcastUpdate () {
  // broadcast messages to all clients
  wss.clients.forEach(function each (client) {
    // filter disconnected clients
    if (client.readyState !== WebSocket.OPEN) return
    // filter out current player by client.udid
    var otherPlayers = Object.keys(players).filter(udid => udid !== client.udid)
    // create array from the rest
    var otherPlayersPositions = otherPlayers.map(udid => players[udid])
    // send it
    console.log("Sending data", JSON.stringify({players: otherPlayersPositions}))
    client.send(JSON.stringify({players: otherPlayersPositions}))
  })
}

console.log('server started')

and front end : (I will let you clean this part)

const socketA = new WebSocket("ws://localhost:8000", ["protocolOne", "protocolTwo"]);
const socketB = new WebSocket("ws://localhost:8000", ["protocolOne", "protocolTwo"]);

function sendPositionUpdate(socket, {udid, x, y, z}) {
  // Construct a msg object containing the data the server needs to process the message from the chat client.
  const msg = {
    type: "message",
    text: JSON.stringify( {udid, x, y, z}),
    id: udid,
    date: Date.now()
  };

  socket.send(JSON.stringify(msg))
}

// Wait for the sockets to connect
setTimeout(() => {
  sendPositionUpdate(socketA, {udid: "12345", x: 0, y: 0, z: 0})
  sendPositionUpdate(socketB, {udid: "54321", x: 10, y: 10, z: 10})
}, 2000)

socketA.addEventListener('message', function (event) {
  console.log('Message from server ', event.data);
});

socketB.addEventListener('message', function (event) {
  console.log('Message from server ', event.data);
});

This works for me