web-dev-qa-db-ja.com

socket.ioをGoogle App Engineにデプロイするにはどうすればよいですか?

私は、socket.ioを使用して最初のnode.jsアプリを作成しました。具体的には、socket.ioによって公開された chat example を実装しました。ローカルで完全に機能します。次に、それをGoogle App Engineにデプロイしてみました(ノードが機能するようにコードを微調整しました)。

すべてが表示され、ノードパーツが正常に機能していることが示されます。ただし、socket.ioパーツが機能していないことを示すチャットは機能しません。デプロイされたアプリ(およびページソース) ここ を確認できます。

追加で何かする必要がありますか? yamlまたはjsonファイルに何かありますか?

yamlコンテンツ:

runtime: nodejs
vm: true

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

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

要するに、これは本番環境では実行できず、 処理中 のようです。正しいアーキテクチャは、概説されているようにGoogle Compute Engineにチャットサーバーを設置することです here

しかし、Google App Engineでsocket.ioを使用するための概念実証として、 websocketsのGoogle appengineサンプル に示すものと非常に似ています。

Socket.ioの場合は、サーバー側で次の手順を実行します。以下のコードスニペット。

  1. 2番目のExpressミドルウェアとサーバーを作成します。
  2. 新しいサーバーでsocket.ioをアタッチ/使用します。
  3. ポート(65080)をリッスンします。
  4. Google Compute Engineのポート(65080)のファイアウォールを開きます。
  5. working repository へのリンク。

socket.ioサーバー側での変更

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

コマンドでファイアウォールを開く

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

これがPaaSの武器の重要な鎧になるので、Googleが本番環境に対応したソリューションをすぐに思いつくことを願っています。

9
npr

GoogleにはWebSockets here を使用したサンプルアプリがあります。正しく機能させるには、次の操作を行う必要があります。

  • クライアントがサーバーに到達できるように、サーバーのファイアウォールポートを開きます
  • Google App Engineで内部IPをフェッチして、クライアントが接続するIPを認識できるようにします
  • REST APIやHTMLページなどを経由してサーバーからIPをエコーアウトする

それはそれであるはずです(ただし、私のWordを使わないでください。これは、ドキュメントでいくつかの調査を行った後に私が見つけたものです)、それが役に立てば幸いです!

Google App Engine内から外部IPを取得する

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"
7
Paradoxis

永続的なソケット接続のGAEサポートが到着しました 2019年2月

これを機能させるには、flex環境を使用し、app.yamlを変更してsession_affinityを含める必要があります。

network:
  session_affinity: true

これを機能させるには、ポート65080を開く必要がありましたが、他の変更は必要ありません。

ディートを読む:

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

5
Charlie

このapp.yaml構成は私にとってうまくいきました:

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

そして、私はこのコマンドでファイアウォールルールを有効にしました:

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