You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Heroku部署Node.js网页游戏服务器端口监听问题求助

解决Heroku部署时端口监听冲突的问题

你遇到的核心问题是代码同时在index.jsnetwork.js中创建了独立的HTTP服务器并监听端口,而Heroku平台只允许单个进程监听它分配的动态端口(通过process.env.PORT获取),重复监听会直接导致应用崩溃。下面是针对性的修改方案:

1. 调整index.js:统一管理HTTP服务器与socket.io

我们需要在index.js中显式创建HTTP服务器,绑定socket.io后再传递给network模块,避免重复创建服务。修改后的代码如下:

var express = require('express');
var app = express();
// 优先使用Heroku分配的端口,本地开发 fallback 到5000
var port = process.env.PORT || 5000;

// 显式创建HTTP服务器(替代app.listen的简写形式)
var http = require('http').Server(app);
// 将socket.io绑定到这个HTTP服务器上
var io = require("socket.io")(http);

app.use(express.static(__dirname + '/'));

// 全局配置常量
var WORLD_SX = 128;
var WORLD_SY = 128;
var WORLD_SZ = 32;
var WORLD_GROUNDHEIGHT = 16;
var SECONDS_BETWEEN_SAVES = 60;
var ADMIN_IP = "127.0.0.1";

// 加载模块
var modules = {};
modules.helpers = require("./js/helpers.js");
modules.blocks = require("./js/blocks.js");
modules.world = require("./js/world.js");
modules.network = require("./js/network.js");
modules.fs = require("fs");
var log = require("util").log;

// 设置全局变量
global.Vector = modules.helpers.Vector;
global.BLOCK = modules.blocks.BLOCK;

// 初始化游戏世界
var world = new modules.world.World(WORLD_SX, WORLD_SY, WORLD_SZ);

// 传入已绑定好的socket.io实例初始化游戏服务器(第二个参数是最大玩家数,可按需修改)
var gameServer = new modules.network.Server(io, 10);

// 统一在index.js中启动端口监听
http.listen(port, function() {
  console.log('Node app is running on port', port);
});

2. 修改network.js的Server函数:移除独立服务创建逻辑

让Server函数不再自行创建HTTP服务器,直接使用传入的socket.io实例即可。修改后的代码片段:

function Server(socketio, slots) {
  var io = this.io = socketio; // 复用传入的socket.io实例
  var s = this;

  io.sockets.on("connection", function(socket) {
    s.onConnection(socket);
  });

  this.eventHandlers = {};
  this.activeNicknames = {};
  this.activeAddresses = {};
  this.maxSlots = slots;
  this.usedSlots = 0;
  this.oneUserPerIp = true;

  // 移除原有的http.listen调用,端口监听已统一放在index.js中完成
}

方案说明

  • Heroku的端口是动态分配的,必须通过process.env.PORT获取,不能硬编码5000(本地开发可保留fallback)。
  • 把HTTP服务的创建和端口监听统一放在index.js中,让network模块复用已有的socket.io实例,彻底避免端口冲突。
  • 这样修改后,本地开发和Heroku部署都能正常运行,无需额外适配。

内容的提问来源于stack exchange,提问作者Fico Pangestu

火山引擎 最新活动