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"
}
}
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.
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.
Google a un exemple d'application utilisant WebSockets ici , vous devez faire ce qui suit pour le faire fonctionner correctement:
Ç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!
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);
});
}
gcloud compute firewall-rules create default-allow-websockets \
--allow tcp:65080 \
--target-tags websocket \
--description "Allow websocket traffic on port 65080"
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
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"