web-dev-qa-db-fra.com

Comment déployer socket.io sur Google App Engine?

J'ai créé ma première application node.js en utilisant socket.io. Plus précisément, j'ai implémenté le exemple de chat publié par socket.io. Cela fonctionne parfaitement, localement. Et puis j'ai essayé de le déployer sur Google App Engine (faire quelques ajustements de code pour que le nœud fonctionne).

Tout apparaît indiquant que la partie nœud fonctionne bien. Cependant, le chat ne fonctionne pas, indiquant que la partie socket.io ne fonctionne pas. Vous pouvez voir l'application déployée (et la source de la page) ici .

Dois-je faire quelque chose de plus? Quelque chose dans les fichiers yaml ou json?

contenu yaml:

runtime: nodejs
vm: true

skip_files:
  - ^(.*/)?.*/node_modules/.*$

Contenu json:

{
  "name": "Chaty",
  "description": "chatrooms app",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "McChatface",
  "engines": {
    "node": "~4.2"
  },
  "scripts": {
    "start": "node app.js",
    "monitor": "nodemon app.js",
    "deploy": "gcloud preview app deploy"
  },
  "dependencies": {
    "express": "^4.13.4",
    "socket.io": "^1.4.6"
  }
}
17
Rian Smith

En bref, cela ne peut pas être fait sur la production et cela semble être travail en cours . La bonne architecture est d'avoir un serveur de chat sur le moteur de calcul Google comme indiqué ici .

Mais comme preuve de concept, l'utilisation de socket.io sur le moteur d'application Google est très similaire à celle indiquée dans exemples d'application Google pour les websockets .

En cas de socket.io, procédez comme suit côté serveur. Extrait de code ci-dessous.

  1. Créez un deuxième middleware et serveur express.
  2. Attachez/utilisez socket.io avec un nouveau serveur.
  3. Écoutez le port (65080).
  4. Ouvrez le pare-feu pour le port (65080) sur le moteur de calcul Google.
  5. Lien vers référentiel de travail .

socket.io change du côté serveur

    var app_chat = require('express')();
    var server1 = require('http').Server(app_chat);
    var io = require('socket.io')(server1);
    server1.listen(65080);

    io.on('connection', function (socket) {
      console.log('user connected');
      socket.on('chat_message', function (data) {
        console.log('client sent:',data);
        socket.emit('chat_message', 'Server is echoing your message: ' + data);
      });
    });

ouvrir le pare-feu par commande

gcloud compute firewall-rules create default-allow-websockets \
    --allow tcp:65080 \
    --target-tags websocket \
    --description "Allow websocket traffic on port 65080"

J'espère que Google trouvera une solution prête pour la production assez tôt, car cela deviendra une armure clé dans tout arsenal PaaS.

9
npr

Google a un exemple d'application utilisant WebSockets ici , vous devez faire ce qui suit pour le faire fonctionner correctement:

  • Ouvrez un port pare-feu pour le serveur afin que les clients puissent accéder à votre serveur
  • Récupérez votre IP interne dans Google App Engine, afin que les clients sachent à quelle IP se connecter
  • Faites écho à votre IP de votre serveur via quelque chose comme une API de repos ou une page HTML

Ça devrait être ça (ne prenez pas ma parole pour ça, c'est ce que j'ai pu découvrir après avoir fait quelques recherches sur les documents), j'espère que ça aide!

Récupération de votre adresse IP externe dans Google App Engine

var METADATA_NETWORK_INTERFACE_URL = 'http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip';

function getExternalIp (cb) {
    var options = {
        url: METADATA_NETWORK_INTERFACE_URL,
        headers: {
            'Metadata-Flavor': 'Google'
        }
    };

    request(options, function (err, resp, body) {
        if (err || resp.statusCode !== 200) {
            console.log('Error while talking to metadata server, assuming localhost');
            return cb('localhost');
        }

        return cb(body);
    });
}

Ouverture du port du pare-feu

gcloud compute firewall-rules create default-allow-websockets \
    --allow tcp:65080 \
    --target-tags websocket \
    --description "Allow websocket traffic on port 65080"
7
Paradoxis

Le support GAE pour les connexions socket persistantes est arrivé en février 2019 !

Pour que cela fonctionne, vous devrez utiliser l'environnement flex et modifier votre app.yaml inclure session_affinity:

network:
  session_affinity: true

Notez que je devais encore ouvrir le port 65080 pour que cela fonctionne, mais aucune autre modification n'était nécessaire pour moi.

Lisez les extraits à:

https://cloud.google.com/appengine/docs/flexible/nodejs/using-websockets-and-session-affinity

5
Charlie

Cette configuration app.yaml a fonctionné pour moi:

runtime: nodejs
env: flex
manual_scaling:
instances: 1
network:
 session_affinity: true

Et j'ai activé les règles de pare-feu par cette commande:

gcloud compute firewall-rules create default-allow-websockets     --allow 
tcp:65080     --target-tags websocket     --description "Allow websocket 
traffic on port 65080"
3
luky