Why do I get this error in Node.js for my online g

2019-08-26 07:23发布

问题:

I have made an online multiplayer game where the backend is nodejs, and sometimes when people test it, they spam bullets or use a script to create lots of players, I get an error. I have limits for this, so there can only be 500 bullets and 20 players in the game, and they all disappear eventually, but even when it doesn't let people create too many bullets/players, when they try to, I get this error:

zlib.js:499
      var newReq = self._handle.write(flushFlag,
                                ^

TypeError: Cannot read property 'write' of null
    at Zlib.callback (zlib.js:499:33)

I am using socket.io with express. There is nothing to do with zlib in my code, and those are the only npm dependencies I am using.

A very slimmed down version of the code I'm using (which should ideally not have been shared in any form):

//Dependencies
var express = require("express");
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var fs = require('fs');

/* a bunch of vars + config */

//Express
server.listen(7654);

//Some functions

//Socket.io Listeners
io.on('connection', function(socket) {

  //Declare Player
  socket.on("declare player", function (data) {
    if (Object.keys(players).length > maxPlayers) return; //Make sure no more than 20 players
    //If statements to check valid data was sent
    var playerdata = {
      //Player Data
    };

    //Referral code stuff

    //Secret Names
    switch (playerdata.name) {
      //Secret player codes for powerups
    }

    playerSecrets[data.id] = data.secret;
    players[data.id] = playerdata;
  });

  //Player Action
  socket.on("player action", function (data) {
    /* Player controls input, mostly redacted */
    switch (data.action.command) {
      case "shoot": //Shoot Bullet
        players[data.id].score--;
        if (bullets.length > maxBullets) return; //Maximum Bullets in Arena (500)
        bullets.push({/*bullet data*/});
        break;
    }
  });

});

//Kill Player
function kill(playerid) {
  delete players[playerid];
  delete playerSecrets[playerid];
}

//Generate stars

//Game loop
setInterval(function () {
  //Emit gamedata to clients
  io.emit("gamedata", {
    players: players,
    stars: stars,
    bullets: bullets,
    referrals: referralData
  });

  //For each player
  for (var i = 0; i < Object.keys(players).length; i++) {
    //Redacted
  }

  //For each bullet
  for (var i = 0; i < bullets.length; i++) {
    //Redacted
  }
}, 1000 / tickSpeed);

I wonder if it's related to things being added to JSON/Arrays, because that is what happens when a player is created/a bullet is shot, and spamming those causes this to happen. See socket.on("player action" and socket.on("declare player".

回答1:

We have had the same issue within same time frame. We did a full look through our dependencies for all uses of the core node library zlib... and found that the only one that changed in our dep list since seeing issue was the "ws" node module. This a dependency of engine.io, which in turn is a dependency of socket.io. https://github.com/socketio/engine.io/pull/564/commits/6a47059eb8164cdf4c6537a7fef6829c90a398f7 ^ boom, engine.io bumped ws up 3 major versions and only released a minor version. So you picked this up if you bumped from socket.io 2.1.1 -> 2.2.0. That is because in between those versions they bumped their engine.io dep to point to the latest minor version: https://github.com/socketio/socket.io/commit/190d22b46e3c2ed18413458a2106322f8bac99f5



回答2:

I was experiencing the same troubles on Ubuntu. But when running the code on my Mac there was no error/bug.

It turned out I had forgotten to confirm the version of Node running on Ubuntu. Turned out to be V8.x is the latest version of NodeJS on Ubuntu's repos. Once I installed LTS with NVM, the bug/error immediately disappeared on Ubuntu as well.

For anyone who may have made this same mistake, check your version of Node first.