Having trouble with web sockets.io inside my Phaser 3 game

151 Views Asked by At
// socket.js (server-side)

const socketIo = require("socket.io");
const { v4: uuidv4 } = require('uuid'); // Import the UUID function

const players = {};

function initializeSocket(server, corsOptions) {
  const io = socketIo(server, {
    cors: corsOptions, // Use the provided CORS options
  });

  io.on("connect", socket => {
    console.log("A user connected");

    // Generate a unique player ID for the connected player
    const playerId = uuidv4();

    // Store the player ID in the `players` object
    players[playerId] = { socket, x: 0, y: 0 };
    console.log(players);

    // Send the player ID to the connected client
    socket.emit("playerId", playerId);

    socket.on("playerPosition", (x, y) => {
      console.log(players[playerId]);
      players[playerId].x = x;
      players[playerId].y = y;
      console.log(`x: ${x} & y: ${y}`);

      console.log("--------ERROR IN CODE---------")

      // Broadcast the updated player positions to all connected clients
      io.emit("updatePlayerPositions", players);

    });

    socket.on("disconnect", () => {
      console.log(`Player ${playerId} disconnected`);
      
      delete players[playerId];

      // Broadcast the updated player positions to all connected clients
      io.emit("updatePlayerPositions", players);
    });
  });

};

module.exports = initializeSocket;
// Socket.js (client-side)

import io from "socket.io-client";

export default class Socket {

    constructor(scene){
        this.socket = null;
        this.scene = scene;
        this.player = {};
        this.players = {};
        this.playerId = "";
    };

    initializeSocketIO(){
        this.socket = io.connect("http://localhost:3001",   { 
            withCredentials: true,
        });

        this.socket.on("connect", () => {
            console.log("Connected to server");
            this.scene.createNewPlayer();
        });

        this.socket.on("playerId", (id) => {
            this.playerId = id;
            console.log(id)
            // Send current player id to GameScene
            this.scene.getCurrentPlayerId(id);
        });

        this.socket.on("updatePlayerPositions", players => {
            this.players = players;
            console.log(this.players);
        });
    
        this.socket.on("disconnect", () => {
            console.log("Disconnected from server");
        });
    };

    handleSocketEmitPlayerPosition(x, y){
        this.socket.emit("playerPosition", x, y);
    };

}
// Socket class (client-side) gets initialized and used in my GameScene.js Phaser 3 class

import Phaser from 'phaser';
import Player from '../classes/Player.js';
import Map from '../classes/Map.js';
import { config } from '../config/configuration.js';
import Socket from '../classes/Socket.js';

export default class GameScene extends Phaser.Scene {
    constructor() {
      super("Game");
      this.currentPlayer = null;
      this.players = {};
      this.playerId = "";
      this.currentMap = "map01";
      this.currentPlayerSpriteSheet = "human01";
    };

    init() {
      console.log("GameScene init() function is called.");
      this.socket = new Socket(this);
      this.socket.initializeSocketIO();
      this.map = new Map(this, this.currentMap);
      this.scene.launch('Ui');
      this.uiscene = this.scene.get('Ui');
    };

    preload() {
      console.log("GameScene preload() function is called.");
    };

    create() {
      console.log("GameScene create() function is called.");
    };

    update() {
      //console.log("GameScene update() function is called.");
      if(this.player){
        this.player.update();
      } else {
        console.log("Initializing player still...");
      };
    };

    createNewPlayer(){
      this.player = new Player(this, config.width / 2, config.height / 2, this.currentPlayerSpriteSheet, this.socket);
      this.player.setUiScene(this.uiscene);
      this.player.setEventListeners();
    };

    getCurrentPlayer(player) {
      console.log(this.player)
      this.currentPlayer = player;
    };

    getAllPlayers(players){
      this.players = players;
    };

    getCurrentPlayerId(id){
      this.playerId = id;
    };

};
// Player.js Phaser 3 class which a Socket.js function gets used at the end of Players update method

import Phaser from 'phaser';

export default class Player extends Phaser.Physics.Arcade.Image {

    constructor(scene, x, y, key, socket) {
      super(scene, x, y);
      this.cursors = this.scene.input.keyboard.createCursorKeys();
      this.scene = scene;
      this.playerX = x;
      this.playerY = y;
      this.key = key;
      this.socket = socket;
      this.chatMessage = "";
      this.frame = 0;
      this.velocity = 500;
      this.setOrigin(0.5, 0.5);
      this.setScale(2);
      this.setTexture(this.key, this.frame);
      scene.physics.world.enable(this);
      scene.add.existing(this);
      scene.cameras.main.startFollow(this, true);

    };

    update() {
      this.handleInputKeys();
      this.setTexture(this.key, this.frame);
      this.chatMessage = this.uiscene.getChatMessage();
      //this.displayChatMessage();
      this.uiscene.setChatMessageEmpty();
      
      this.socket.handleSocketEmitPlayerPosition(this.x, this.y);
    };

    handleInputKeys() {
      this.setVelocity(0);
      
      if(this.cursors.left.isDown) {
        this.frame = 24;
        this.setVelocityX(-this.velocity);
        this.playerX -= this.velocity;
      } else if(this.cursors.right.isDown) {
        this.frame = 16;
        this.setVelocityX(this.velocity);
        this.playerX += this.velocity;
      } else if(this.cursors.up.isDown) {
        this.playerY -= this.velocity;
        this.frame = 8;
        this.setVelocityY(-this.velocity);
      } else if(this.cursors.down.isDown) {
        this.playerY += this.velocity;
        this.frame = 0;
        this.setVelocityY(this.velocity);
      };
 
    };

    displayChatMessage(){
      console.log(this.chatMessage);
    };

    setEventListeners(){
      this.uiscene.events.on('chat', this.onChatMessage);
    };

    setUiScene(scene){
      this.uiscene = scene;
    };

    onChatMessage(msg) {
      this.chatMessage = msg;
    };

};

I have been stuck on this error I've been getting for about 4 days now, googling, using chat gpt, my own logic and looking over the socket.io documentation and source code and can't seem to find or try anything to resolve this issue. My socket gets connected when a user enters the game, the playerId gets logged on client side but something goes wrong in the playerUpdatePositions() listener/emitter that shuts down the server and gives this error message in my web developer console...

GET http://localhost:3001/socket.io/?EIO=4&transport=polling&t=OicqNzG net::ERR_CONNECTION_REFUSED
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
XMLHttpRequest.send (async)
create @ polling.js:298
Request @ polling.js:237
request @ polling.js:190
doPoll @ polling.js:215
poll @ polling.js:96
doOpen @ polling.js:56
open @ transport.js:46
open @ socket.js:170
Socket @ socket.js:111
open @ manager.js:108
(anonymous) @ manager.js:328
setTimeout (async)
reconnect @ manager.js:321
(anonymous) @ manager.js:331
onError @ manager.js:123
Emitter.emit @ index.mjs:136
onError @ socket.js:541
Emitter.emit @ index.mjs:136
onError @ transport.js:38
(anonymous) @ polling.js:218
Emitter.emit @ index.mjs:136
onError @ polling.js:320
(anonymous) @ polling.js:294
setTimeout (async)
xhr.onreadystatechange @ polling.js:293
polling.js:298 

When I first start the server before entering the game where it crashes and curl it this happens...

client git:(bryce) ✗ curl "http://localhost:3001/socket.io/?EIO=4&transport=polling" 
0{"sid":"G7hipa5V3oSVL0RHAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000}

It seems's to happen in the updatePlayerPositions() socket code. I'm trying to pass the players object to the client-side so I can use it on client-side to update where the rest of the players are currently excluding the user to not having a back to back/jarring effect. I commented where I think the error is located but then again I'm still learning so something else may be causing it. I pass cors options from my server.js file to be used within my socket.js (server-side) file which is this code below...

const corsOptions = {
    origin: [
        'http://127.0.0.1:3000', 
        'http://localhost:3000',
        'http://127.0.0.1:3001', 
        'http://localhost:3001',
    ],
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE'
    credentials: true,
    optionsSuccessStatus: 204,
};

Server logs the player and then the players object on server-side before giving this message at the crash...

Server is listening on port 3001
Connected to MongoDB
A user connected
{
  '9040ca1f-5c1b-4b0c-9e82-8dc60cc26544': {
    socket: Socket {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      nsp: [Namespace],
      client: [Client],
      recovered: false,
      data: {},
      connected: true,
      acks: Map(0) {},
      fns: [],
      flags: {},
      server: [Server],
      adapter: [Adapter],
      id: 'xciBu-vKWmDGytdZAAAB',
      handshake: [Object],
      [Symbol(kCapture)]: false
    },
    x: 0,
    y: 0
  }
}
{
  socket: Socket {
    _events: [Object: null prototype] {
      error: [Function: noop],
      playerPosition: [Function (anonymous)],
      disconnect: [Function (anonymous)]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    nsp: Namespace {
      _events: [Object: null prototype],
      _eventsCount: 1,
      _maxListeners: undefined,
      sockets: [Map],
      _fns: [],
      _ids: 0,
      server: [Server],
      name: '/',
      adapter: [Adapter],
      [Symbol(kCapture)]: false
    },
    client: Client {
      sockets: [Map],
      nsps: [Map],
      server: [Server],
      conn: [Socket],
      encoder: [Encoder],
      decoder: [Decoder],
      id: 'Lx6IGivYWYMxLBItAAAA',
      onclose: [Function: bound onclose],
      ondata: [Function: bound ondata],
      onerror: [Function: bound onerror],
      ondecoded: [Function: bound ondecoded],
      connectTimeout: undefined
    },
    recovered: false,
    data: {},
    connected: true,
    acks: Map(0) {},
    fns: [],
    flags: {},
    server: Server {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      _nsps: [Map],
      parentNsps: Map(0) {},
      parentNamespacesFromRegExp: Map(0) {},
      _path: '/socket.io',
      clientPathRegex: /^\/socket\.io\/socket\.io(\.msgpack|\.esm)?(\.min)?\.js(\.map)?(?:\?|$)/,
      _connectTimeout: 45000,
      _serveClient: true,
      _parser: [Object],
      encoder: [Encoder],
      opts: [Object],
      _adapter: [class Adapter extends EventEmitter],
      sockets: [Namespace],
      eio: [Server],
      httpServer: [Server],
      engine: [Server],
      _corsMiddleware: [Function: corsMiddleware],
      [Symbol(kCapture)]: false
    },
    adapter: Adapter {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      nsp: [Namespace],
      rooms: [Map],
      sids: [Map],
      encoder: [Encoder],
      [Symbol(kCapture)]: false
    },
    id: 'xciBu-vKWmDGytdZAAAB',
    handshake: {
      headers: [Object],
      time: 'Sat Oct 14 2023 07:55:08 GMT-0700 (Pacific Daylight Time)',
      address: '::1',
      xdomain: true,
      secure: false,
      issued: 1697295308754,
      url: '/socket.io/?EIO=4&transport=polling&t=OikhnUm',
      query: [Object: null prototype],
      auth: {}
    },
    [Symbol(kCapture)]: false
  },
  x: 0,
  y: 0
}
x: 640 & y: 360
--------ERROR IN CODE---------
/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:28
function hasBinary(obj, toJSON) {
                  ^

RangeError: Maximum call stack size exceeded
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:28:19)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)
    at hasBinary (/Users/bryceberwald/Desktop/Savages-Online/server/node_modules/socket.io-parser/build/cjs/is-binary.js:49:63)

Node.js v20.3.1
[nodemon] app crashed - waiting for file changes before starting...

Client is on 3000 and server is on 3001. I appreciate all the help that could be given for helping me resolve this issue. I have been stuck and need some guidance. Thank you.

0

There are 0 best solutions below