无法连接到Google Cloud Compute Engine上的NodeJS WS服务器

时间:2017-03-25 19:25:47

标签: javascript node.js linux google-compute-engine

我创建了两个构成小型多人游戏的JavaScript文件(服务器文件和客户端文件)。当我使用node server.js在本地运行服务器文件时,它开始运行。然后,我可以使用node client.js运行客户端文件来玩游戏,一切正常。但是,当我尝试在Linux实例(谷歌云上的计算引擎)上主持游戏时,我无法从客户端连接到它。我在nodeJS中使用ws库作为websockets。

以下是代码:

server.js

const WebSocket = require('ws');
const util = require('util');

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

var magicNum = Math.ceil(Math.random() * 5);
var champion = "James";
var connections = [];

console.log('server listening...');

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

    connections.push({
        ws: ws,
        name: "",
        score: 0
    });

    ws.on('message', function incoming(message, flags) {

        var currentPlayer;

        for (var i = 0; i < connections.length; i++) {
            if (connections[i].ws === ws) {
                currentPlayer = connections[i];
            }
        }

        var response;
        var obj = JSON.parse(message);

        if (parseInt(obj.guess) === magicNum) {

            currentPlayer.score++;
            response = "HOLY COW! YOU GUESSED THE MAGIC NUMBER!!!" +
                "I now declare you, " + obj.name + ", the new champion! (You have correctly guessed ( "
                + currentPlayer.score + " ) numbers)";
            champion = obj.name;
            magicNum = Math.ceil(Math.random() * 5);

            ws.send(JSON.stringify({ response: response, prompt: true }));

            for (var i = 0; i < connections.length; i++) {
                if (connections[i].ws !== ws) {
                    response = "Uh oh, too slow! " + obj.name + " correctly guessed the number and is the new champion"
                        + " with " + currentPlayer.score + " correct guesses!";
                    connections[i].ws.send(JSON.stringify({ response: response, prompt: false }))
                }
            }

        } else {
            response = "Sorry, that's not the magic number. The champion is still " + champion + ".";
            ws.send(JSON.stringify({ response: response, prompt: true }));
        }

    });

    ws.on('close', function (a, b) {

        for (var i = 0; i < connections.length; i++) {
            if (connections[i].ws === ws) {
                connections.pop(i);
                console.log('removing connection from array');
            }
        }
        console.log('current connections now: ' + connections.length);
    })
});

client.js

const WebSocket = require('ws');
var prompt = require('prompt');

//const ws = new WebSocket('ws://localhost:8889');
const ws = new WebSocket('ws://35.185.74.130:8889');

var clientName = '';

function beginPromptForGuess() {

    var numberSchema = {
        properties: {
            number: {
                description: 'Please guess an integer between 1 and 20',
                pattern: /^\d+$/,
                message: 'please enter an integer.',
                required: true
            }
        }
    };

    console.log('prompt is: ' + prompt.stopped + " " + !prompt.started)

    if (prompt.stopped || !prompt.started) {
        console.log('starting prompt');

        prompt.get(numberSchema, function (err, result) {
            if (result) {
                console.log('got number');
                ws.send(JSON.stringify({ name: clientName, guess: result.number }));

            }
        })
    }
}

ws.on('open', function open() {

    setTimeout(function () {
        console.log('Hey, let\'s play a game!');

        var nameSchema = {
            properties: {
                name: {
                    description: 'First, what is your name?',
                    pattern: /^[a-zA-Z\s\-]+$/,
                    message: 'Name must be only letters, spaces, or dashes',
                    required: true
                }
            }
        };

        prompt.get(nameSchema, function (err, result) {
            if (result) {
                clientName = result.name;
                console.log('Hi there, ' + result.name + '!');
                console.log('Let\'s play!');
                beginPromptForGuess();
            }
        });
    }, 500);

});

ws.on('message', function incoming(data, flags) {
    var obj = JSON.parse(data);
    console.log('Server says: ' + obj.response);

    if (obj.prompt) {
        beginPromptForGuess();
    }
});

创建linux实例并使用SSH“在浏览器窗口中打开”选项后,在home / mrjim目录中打开我实例内的shell。该实例已经有节点,所以我将服务器代码粘贴到一个文件中,运行npm init创建一个package.json文件,安装了ws库。然后我跑了node server.js它似乎正在运作:

enter image description here

但是,当我尝试从客户端连接到它时,shell挂起一段时间并提供此输出:

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED 35.185.74.130:80
    at Object.exports._errnoException (util.js:1026:11)
    at exports._exceptionWithHostPort (util.js:1049:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1085:14)

我是否在服务器文件的位置或者我如何编写ip / ports时出错了?感谢。

此外,这是我的Linux实例的Google云配置: enter image description here

我还在防火墙规则中打开了端口,但我仍然无法从客户端连接:

enter image description here

1 个答案:

答案 0 :(得分:1)

在您的Google云设置的屏幕截图中,您似乎将外部IP设置为 * Ephemeral * 。要从外部客户端(例如本地计算机的命令shell)访问它,您应该将其更改为统计信息ip。另外,对于多人游戏的后端,我建议使用更安全的SSL端口443而不是8889。

祝你好运!