15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Google Cloud Run は WebRTCのシグナリングサーバーに使えるか?

Last updated at Posted at 2019-05-29
1 / 19

はじめに

この資料は 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 で実行

CloudBuildでビルド
$ gcloud builds submit --project cloud-run-webrtc1to1 --tag gcr.io/cloud-run-webrtc1to1/webrtc-1to1
CloudRunにデプロイ
$ 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

Chrome DevConsoleのNetworkタブ
cloudrun_ws.png

WebSocketが繋がらない (400 Bad Request)


Cloud Run の制約

Container runtime contract より

  • 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 に設定 → シグナリングできない
    • ※どころか、コンソールの動きが一部おかしくなる??

シグナリングには、別の手段が順当

ちなみに Google App Engine FE は IaaSより高い


まとめ

  • Cloud Run 便利そう
  • が、シグナリングザーバーには向いてない

どうもありがとうございました!

15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?