はじめに
この資料は WebRTC Meetup Tokyo #21 のLT発表資料です。
(が、WebRTC成分はゼロです)
自己紹介
- インフォコム株式会社 がねこまさし
 - @massie_g
 - WebRTC Meetup Tokyo / Begginers Tokyo スタッフ
 
Cloud Run とは
- Cloud Run は Google Cloud Platform (GCP)の新しいサービス
 - 自分で作ったコンテナを、Googleが用意したサーバー環境上で動かせる
 - http(s) の口を持ったWebアプリ/Web APIサーバーを手軽に作れる
 - スケーリングも勝手に面倒見てくれる
 
Cloud Run でできないこと
- コンテナを使っていても、できないことがある
 - 単体ではステートを持てない
 - データーの永続化はできない
 
→ 他のサービスを組み合わせて利用
※WebRTC的に気になること
- シグナリングサーバーに使えるのか? (WebSocketは使えるか?)
 
Cloud Run を使うには
- 準備
 - コンテナのビルド
 - コンテナのデプロイ
 
詳しくは別記事にて ... Google Cloud Run を使うまで
サンプルの準備
- シンプルな、1対1のビデオチャットのサンプル
 - サーバー側(コンテナ)は、Webサーバーと、WebSocketサーバー機能を持つ
- Node.js + express + ws
 
 - 同一ポートで、httpとwebsocketを使用
- PORT環境変数で指定されたポート番号を使用
 
 
サーバーのソースコードの抜粋
GitHubはこちら https://github.com/mganeko/webrtc_1to1
// --- get PORT from env --
let port = process.env.PORT;
// --- prepare server ---
const http = require("http");
const WebSocketServer = require('ws').Server;
const express = require('express');
const app = express();
app.use(express.static('public'));
let webServer = null;
const hostName = 'localhost';
// --- http ---
webServer = http.Server(app).listen(port, function () {
  console.log('Web server start. http://' + hostName + ':' + webServer.address().port + '/');
});
// --- websocket signaling ---
const wsServer = new WebSocketServer({ server: webServer });
コンテナのビルド
Dockerfile
# Use the offical node.js image
FROM node:10.15.3-alpine
RUN mkdir /root/work 
WORKDIR /root/work/
RUN apk add git
RUN git clone https://github.com/mganeko/webrtc_1to1.git
WORKDIR /root/work/webrtc_1to1
RUN npm install
# Run the web service on container startup.
EXPOSE 8080
CMD [ "node", "server_1to1.js" ]
※本当は node を直接起動するのは良くないらしい
「Docker node PID 1」で検索
ローカルでコンテナを実行
$ docker build -t mganeko/webrtc_1to1 .
$ docker run -d -e PORT=1323 -p 8002:1323 --name webrtc mganeko/webrtc_1to1
mganeko/webrtc_1to1 はイメージ名(適宜置き換えてください)
2つのブラウザで http://localhost:8002 に接続 → OK
Cloud Run で実行
$ gcloud builds submit --project cloud-run-webrtc1to1 --tag gcr.io/cloud-run-webrtc1to1/webrtc-1to1
$ gcloud beta run deploy --project cloud-run-webrtc1to1 --image gcr.io/cloud-run-webrtc1to1/webrtc-1to1
それぞれの値は適宜置き換えてください。
cloud-run-webrtc1to1 ... プロジェクトID
webrtc-1to1 ... サービス名
gcr.io/cloud-run-webrtc1to1/webrtc-1to1 ... イメージのURL
結果は NG
WebSocketが繋がらない (400 Bad Request)
Cloud Run の制約
- The container must listen for requests on 0.0.0.0 on the port defined by the PORT environment variable.
 - Your container instances must start an HTTP server within 4 minutes after receiving a request.
 
どうやらHTTPのみ使えて、WebSocketは使えない
※(2021.02.07追記)CloudRunでWebSocketやHTTP/2, gRPCが使えるようになりました。
無理やりシグナリングするには
- HTTPで無理やり → Long Polling (COMET) しかない
 
自分で Log Polling 実装するにはどうすれば..?
あ、それって Socket.io がフォールバックでサポートしているはず!
Socket.io版サンプル
- シンプルな、1対1のビデオチャットのサンプル
 - サーバー側(コンテナ)は、Webサーバーと、Socket.ioサーバー機能を持つ
- Node.js + express + socket.io
 
 - 同一ポートで、httpとsocket.io(websocketとフォールバック)を使用
- PORT環境変数で指定されたポート番号を使用
 
 
サーバー側ソースコードの抜粋
// --- get PORT from env --
let port = process.env.PORT;
// --- prepare server ---
const http = require("http");
const express = require('express');
const app = express();
app.use(express.static('public'));
let webServer = null;
const hostName = 'localhost';
// --- http ---
webServer = http.Server(app).listen(port, function () {
  console.log('Web server start. http://' + hostName + ':' + webServer.address().port + '/');
});
// --- socket.io server ---
const io = require('socket.io')(webServer);
console.log('socket.io server start. port=' + webServer.address().port);
結果
- websocket接続はエラー
 - xhr poll でシグナリングはできる
 
時間があったらデモ
厳密には
- リクエストが増えると、自動的にスケールアウト
- デフォルト設定では 80
 
 - 実運用では、同じインスタンスに繋がるとは限らない → シグナリングできない可能性あり
- 試しに同時リクエスト数を 1 に設定 → シグナリングできない
 - ※どころか、コンソールの動きが一部おかしくなる??
 
 
シグナリングには、別の手段が順当
- リアルタイム通信サービスを使う (Firebase, milkcocoaなど)
 - Cloud Run on GKE を使う(多分、行けるはず)
 - Google App Engine を使う
- Standard Environment ... WebSocket NG
 - Flexible Environment ... WebSocket OK
 
 - Google Compute Engine や、他のIaaSを使う
 - heroku も WebSocket 使える様子... Using WebSockets on Heroku with Node.js
 
ちなみに Google App Engine FE は IaaSより高い
まとめ
- Cloud Run 便利そう
 - が、シグナリングザーバーには向いてない
 
どうもありがとうございました!
