2017-03-25 3 views
1

Ich habe zwei JavaScript-Dateien (eine Serverdatei und eine Clientdatei) erstellt, die ein kleines Mehrspieler-Spiel bilden. Wenn ich die Serverdatei lokal mit node server.js starte, wird es ausgeführt. Ich kann dann die Client-Datei mit node client.js ausführen, um das Spiel zu spielen, und alles funktioniert gut. Wenn ich jedoch versuche, das Spiel live auf einer Linux-Instanz zu hosten (Compute Engine in der Google Cloud), kann ich keine Verbindung zu den Clients herstellen. Ich verwende die ws Bibliothek für Websockets in NodeJS.Verbindung zu NodeJS WS-Server in Google Cloud Compute Engine nicht möglich

Hier ist der Code:

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(); 
    } 
}); 

Nachdem ich die Linux-Instanz erstellt und verwendet, um die SSH "Open in Browser-Fenster" Option um eine Shell innerhalb meiner Instanz im Verzeichnis home/mrjim zu öffnen. Die Instanz hatte bereits einen Knoten, also habe ich den Server-Code in eine Datei eingefügt, npm init ausgeführt, um eine package.json-Datei zu erstellen, die ws-Bibliothek installiert. Dann lief ich node server.js und es scheint zu funktionieren:

enter image description here

Allerdings, wenn ich versuche, von dem Client um eine Verbindung herzustellen die Schale für eine Weile hängt und diesen Ausgang zu geben:

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) 

Mache ich etwas falsch mit dem Speicherort der Serverdateien oder wie schreibe ich die IP/Ports? Vielen Dank.

Auch hier sind meine Google Cloud-Konfigurationen für die Linux-Instanz: enter image description here

Ich habe auch Ports in der Firewall-Regeln geöffnet, aber ich kann immer noch nicht aus dem Client eine Verbindung herstellen:

enter image description here

+1

sieht aus wie Ihre IP-Bereich ist Ihre interne IP. Finden Sie Ihre öffentliche IP-Adresse. (Sie können dies überprüfen, indem Sie "what's my ip" in der Registerkarte chrome eingeben.) Fügen Sie dies in Ihrem IP-Bereich hinzu. Andernfalls erlauben Sie alle Anfragen, indem Sie Ihre IP-Adresse als 0.0.0.0/0 angeben. es hat für mich funktioniert. Bitte prüfe. – Balu

Antwort

1

Im Screenshot Ihrer Google Cloud-Einstellungen sieht es so aus, als hätten Sie die externe IP-Adresse * Ephemeral *. Um von externen Clients (z. B. der Befehlsshell Ihres lokalen Computers) darauf zuzugreifen, sollten Sie dies in eine Statistik-IP ändern. Auch für das Backend von einem Multiplayer-Spiel würde ich empfehlen, die viel sicherer SSL-Port 443 statt 8889.

Viel Glück mit!

Verwandte Themen