Webでできる体験を考える

折原レオナルド賢氏:それでは「Webでできる体験を考える会」ということで始めたいと思います。去年の今頃、こんな記事を書かせていただきました。

もしかしたらこれによって今回呼んでもらったのかなと思いますので、この話の内容も含めていろいろ「Web APIってどういうもの?」という発表をしていきたいと思います。

この記事で「Sound Walker」というWebのAppをリリースしましたので、この話をしつつ、どうやってWeb APIを使っていくのかについてお話ししたいと思います。

今日はいろいろなWeb APIを触るのですが、先ほどの基調講演みたいに最新のAPIがたくさん出るわけではありません。ですが、「考える会」と言っているぐらいなので、初心者はもう今すぐ使えるようになれますし、応用したい人は「こういう組み合わせができたらおもしろいよね」という話があったり。エンジニアではない人にとっては「こういう発想があるんだね」と思っていただける話ができればと思います。

まずは鳴るもの・動くもの。こんな感じのAPIを動かしてみたいと思います。

鳴るもの。

鳴るものといえばWeb Audio APIです。古くからあるAPIで、使ったことある人もいると思います。ただ、音を鳴らすサイトはあまりないので、実際に触ったことがない人ももしかしたらいらっしゃるかもしれません。

まずはcontextを作ってから、こんな感じでノードを生成していきます。

何かというと、sourceNode、gainNode、biquadFilterNode、AnalyserNode、こんな感じでそれぞれ機能があるものに対応して作っていくのがWeb Audio APIです。

それぞれ何ができるのかというと、AudioBufferSourceNodeは、音源を設定したり、スタート・ストップしたりする機能になります。

GainNodeは音量を調節したり。BiquadFilterNodeはあらかじめ用意されているエフェクターをかけることができるものです。AnalyserNodeはオーディオの波形を手に入れたり、オーディオが今鳴ってる情報はどういうものかを見ることができるノードになっています。

ここで、getByteTimeDomainDataというのとFrequencyDataというのがあります。

それぞれ何かというと、こういうデータになってます。上がTimeDomainData、下がFrequencyData。要は上のデータをフーリエ変換した値が下になるんですが、こういうデータを取ることができます。

Audio APIはシンプルで、実際のオーディオの配線をつなぐようにそれぞれのノードをコネクトすることでオーディオを再生できます。エフェクターを通して、音量のGainを通して、最後に再生するって感じです。

ちなみに先ほど紹介したSound Walkerというゲームに関しては、こんなぐちゃぐちゃな配線になっています。

ちょっとわかりづらいのでフォーカスして説明します。ここの部分はGainNodeを2つ合わせていて、2つの音声、AとBのトラックをクロスフェードしています。

これは2つのGainNodeを使って、片方の値を−1することでクロスフェードを生み出しています。

また、ここでは波形を出しているのですが、BufferSource、要は音源のノードからGainNode、音量を取って、BiquadFilter、HighPass・LowPassというエフェクトをかけて、AnalyserNodeがどういう波形が出ているのか存在している、このコネクトのルートです。

これは何をやっているかというと、こんな感じでエフェクトをかけて、これを実際にエフェクトをAnalyserNodeでかけたデータを受け取ってバックグラウンドで表示するというものです。

WebGLことはじめ

次、動くものですね。動くものといえばWebGLです。WebGLも古くからあるので触ったことのある人も多いかと思います。ここでWebGLとはどんなものなのか基礎的な話をすると、WebGLができる人ってけっこう能力高い方だと思うので、ここではシンプルにライブラリはどうかという提案をしたいと思います。

WebGLだとだいたいこの2つ、three.jsとPixiJSが有名です。

three.jsは3Dでガチャガチャオブジェクトを動かします。さきほどのSound Walkerも、実はthree.jsを使っています。PixiJSは2Dなんですがリッチな表現をするときに使えたりします。PixiJSで3Dができないわけではないです。

では、ことはじめ的な内容なんですが、three.jsだったらまずはsceneとcameraとrenderer.を作ります。ここでsceneとcameraができたときに、rendererをここのDOMにappendすることでcanvasが生成されます。

このcanvasにthree.jsが書き込んでくれるので、このcanvasを利用することによって映像がガチャガチャ動くようになています。

では、オブジェクトを入れましょう。

オブジェクトはgeometryとmaterialというものに分かれています。例えばここでは今BoxGeometryというものとMeshBasicMaterialというものを作っています。この2つをMeshというものにかませるとcubeができて、cubeをsceneに、これさっき1個前のスライドで作ったものなんですけど、sceneにaddすると立方体が設置されます。

こはシンプルで、こんなんRead Meの最初の行の内容だと思うのですが、本当にこれだけですw。あとはどんなコンテンツを載せるかが重要です。

では、ビジュアライザー何だったのかというと、この1本白くなったところ、ここが1つのShapeといわれるcontent、先ほどのmaterialになってます。

何かというと、Three.Shapeを宣言して、OFFSETというのはデザイン上必要なので中心からの距離を計算しています。moveToというものでパスを描きます。Illustratorなのでパスを少し描いてください。数式はとくに解説しませんが、こんなもんだと思ってください。

moveToすると、この矢印のところに位置が決まって、lineTo、lineTo、lineToというパスがクローズします。これはシンプルな四角形ができていて、ここの、これで今1つの波形……波形の1つとします。

この数式の振幅なんですが、これはgetByteFrequencyDataで取れるこの1本です。なのでわかりやすく言うと、FrequencyDataが動いてるやつをぐるぐると円形に配置した感じになっています。

画面の転換で使った技術

もう1個、画面の転換です。実はゲームでは演出がありました。画面全体が暗転して次の画面にいくみたいなトランジションです。

これも別にCSSとかではなくて、実は3枚層があって、three.jsで背景にビジュアライザーがあって、操作できるReactのコンポーネントがあって、一番前にもう1個canvasがあるんですけど、これがトランジションしています。

何が起きているかというと、three.jsでもう1点おもしろい使い方があって、シェーダーって聞いたことあるかと思うし、または使ってるかと思うんですけど、シェーダーをここにかけるShaderMaterialというメソッドもあります。materialをShaderMaterialに置き換えて差し込むと、GLSL言語を書けます。

これが具体的な例です。

何をしているか分かりづらいかもしれませんが、簡単に言うとmixRatioがここにあって、テクスチャが2つ、「Sound Walker」ってロゴが出ているのと、バラバラバラって変わるアニメーションのテクスチャ、その2つをmixRatioによって切り替えることで画面の転換を行います。

「PWAの会じゃないの?」みたいな感じになってしまいますが、ぜんぜんAndroidやiPhoneでナチュラルに動くしサクサクに動くので使ってみてください。

あとはpostprocessingというものがあります。

これもスマホでガリガリ動くのですが、ちょっと時間がないので割愛します。スライドにはいっぱい書いてあるので、ぜひ見てください。

表現・体験を考える

ここからが僕的には本題のところです。表現や体験を考えてみましょう。今のAPI、古いAPIも使ってくのですが、どうやって使ったらおもしろいのかという考えを僕が話したいと思います。

このセクションはエモい感じではじめたいと思います。

遠くない未来であれば、Webのゲームも前進的に、Progressiveに遊べるんじゃないかと思いますし、もっとそうなってほしいと思います。

では、アプリでもできるのになぜWebでやるのかというと、URLを踏めば遊べるというすごさとか、Webでできるからすぐに遊べる・捨てられる。

例えばテーマパークでアプリをインストールするとかあると思うんですよ。でもそれって絶対家に帰ったらアンインストールするじゃないですか。それならWebで遊んで、すぐ捨てるということができるので便利ですし、シェアもしやすいです。

こういうことを活かすと、ただのWebの画面の話じゃなくて、さっきみたいにテーマパークでどうするとか、「遊び方がWebを超えて、もっとProgressiveになるんじゃない?」って思ってます。

例えば、ゲームセンターってみなさんどんなときに行きますか? 行かない人もいると思いますが家ではできない遊び方をしたいときにゲームセンターに行きます。僕は音ゲーが好きなので、こういう筐体で遊びたいです。

つまり、自分で揃えられない機材があること。臨場感たっぷりのスピーカーやコントローラー、または大迫力のビジュアライザーがあってこういうところにPWAで小さくスマホの中で遊んでたゲームを持っていくと、コネクトして遊べる、みたいなことができるとおもしろいんじゃないかと思ってます。

その逆で、もしPWAで展開しているアプリをゲームセンターで初めて遊んで、「PWAでもあるから遊んでね」とQRコードを出せば、持って帰って遊べるわけです。

そうすると続きをスマホで遊べて、もっと迫力ある遊び方したい、違う遊び方をしたいなと思ったら、ゲームセンターやテーマパークに持っていくともっと遊べるという、前進的な遊び方ができるのではないかと考えています。

ここでちょっと大げさなデモをしようと思ってます。DJミキサーが偶然ここにあるので、DJミキサーをBluetoothでこのAndroidにつないで、エフェクターをかけてみましょう。さっきのSound Walkerを遊んでみます。

AirServerというのを立ち上げて画面のキャストができるようになっているんですが、みなさんもできちゃうので、ぜひ送らないでください。Macbookというのが僕のアカウントなので、ぜひ画面を送らないでください(笑)。

(映像が流れる)

こんな感じのデモです。ありがとうございます。今のはMIDI Bluetoothというものを使っています。詳細はスライドを見てください。

MIDI Bluetoothというのが実は存在していて、これはAPIの話ではなくて機材の話です。ここに今ついているBluetoothの端末があって、MIDIの情報をBluetoothに投げることができます。

こうすることによって、実際Androidみたいに「なにもMIDI差し込むポートもないしUSB差し込むポートもないよ」みたいなところでもBluetooth経由で何かできるようになるので、Bluetoothがあればさっきみたいなゲームをうまく遊んだりもできるようになると思います。なので、MIDIのアクセスも取ってたほうがいいですね。

Web AssemblyとWeb Worker

2つ目のWebAssemblyとWeb Workerです。今までのセッションはけっこう見せるものがあったと思うんですが、こちらはけっこうコードベースになるので、ちょっと地味かもしれません。

みなさんもよくご存じのWebAssemblyだと思うんですが、ブラウザのバイナリコードを用意して、JavaScript側から動かす技術です。

CとかRustとか、最近だとKotlin/Nativeからwasmに変換することができるので、これらの資産をWebに持っていくことができますよね。

簡単な例でCからwasmへの道のりを考えてみます。

左のようなadd.cみたいなコードを書くと、Emscriptenを使ってwasmに変換できます。細かい使い方はスライドにあるのでそちらをぜひ見てください。

では、JavaScriptで動かすとどうなるかというと、このWebAssemblyというクラスの中にはinstantiateStreamingというものがあるので、これを使うとwasmを動かせます。これが一番効率的でシンプルなやり方になっています。

何がおもしろいかというと、wasmからインポートした関数、当たり前なんですけど、無理やりこんな感じでconsole.log()で関数見てみるとnative codeって出ます。なので、普通の関数ではなくて、持ち込んだコード、ブラウザのバイトコードが入っていることがわかります。

wasm、Cとか面倒くさいと思うんですが、もし使ったことない人がいれば、AssemblyScriptがおすすめで、TypeScriptの感覚でwasmを書けます。

ちょっと型は違うんですけど、npmで入れて、npxとかでコンパイルするとできます。「CやC++は過剰なんだけど、ちょっとJSのここだけ速くしたい」「この計算はよく使うから、この計算はモジュール化して使いまわしたい」みたいなときに便利です。

Web Workerを組み込む

Web Workerも、みなさん言わずと知れた、Webで重い処理をするときにWorkerに委託してそれを返してもらうみたいな処理ができる、別スレッドにする技術の1つです。

これはとくにPWAだとよく使いますが、重い処理をガリガリ書きたいときに、メインスレッドを止めちゃうと、アプリとして成り立たなくなるのはよくないので、けっこう裏に飛ばすのは、PWAでやりがちだと僕は感じます。

どう使うかというと、new Workerに普通のJSファイルを読み込ませます。

このworker.jsはシンプルなJavaScriptなんですが、受け渡し自体はpostMessage経由で行います。

なにをするかというと、クライアントからpostMessageで送ることができて、かつ、addEventListenerでmessageを見ることで、Workerから来るmessageも観測できます。Worker側も同じようにpostMessageをクライアントに送って、messge、addEventListenerで観測できます。

これでデータの受け渡しができるんですが、困ることもあります。

「重い処理をするからには、重いファイルをWorkerに渡すんじゃない?」ということがあります。例えば動画をなにかしたいから動画を渡す、500MBの動画を渡すのであれば、postMessageするとコピーされちゃうので1GBのメモリをひっ迫することになります。そのあたりはさすがに考えられていて、Transferable ObjectというものがWorkerには存在します。

Transferable Object

何かというと、先ほどのpostMessageでいろいろなデータ、オブジェクトが送れて、オブジェクトの中の1つがUint8Array、この型のどれかであればバッファがあると思うので、バッファを第2引数に置くと、値、参照渡しのような感じですぐ渡せます。

これで渡したメッセージというのは、クライアントから所有権がWorkerに移るので、一瞬でクライアントからデータがなくなります。Workerに送ったあとに見てみると空の配列にされていて。まぁ0って、データがないので0が大量にあって500MBあるんですけど、これでかなり大きいデータがWorkerに移ったよという感じになります。

じゃあ実際Transferable Objectを使うと速いよね、きっとって思うと思うんですよ。なので比較してみましょう。クライアントでそのまま送るケースとTransferable Objectを使ったケースです。

タイマーのためにSTARTっていうのがあるんですけど、ここでデータを生成してバッファで送ります。

Workerの受け取り側は、STARTって来たら時間を保持して、パフォーマンスの計測用のAPIがまた別にある。こういったものがあって、次のconsoleで終わった時間から引き算しましょう。

見てみると、そのまま送る場合、500MBのファイルをパンって送ると、866msec。Webの感覚だとけっこう遅いと思います。Transferable Objectiveにすると、なんと1ミリかからないですね。これはめちゃくちゃ速いので、基本的にはこれを使うし、メモリもひっ迫しないので、これが便利ですよねっていうお話。まぁ、普通ですね。

画像、動画における表現と体験を考える

それでは、表現/体験を考える。最近、画像や動画アプリがどんどん高機能になってるんですよね。撮ったらすぐクラウドに上がって、誰が写っているかもまとめてくれるし、どこで撮ったものかもまとめてくれる。もうむちゃくちゃ便利ですね。すぐ写真を探すときに便利です。

一方で、こういう人もいると思うんですね。

自分の写真・動画を“とやかく”されたくない。とやかくされたくない人だってメリットはわかるんですよ。だって、クラウドに上げたら手元の容量を減らせるし、便利なのはわかってる。ただ、自分の写真を外に出したくないし、誰かに分析されたくない。

そういうときに現れるのがこういう敵です。「プライベートクラウドみたいのを使えば、自分で設定してうまくクラウドみたいに使えるんじゃないの?」みたいな話が出てくると思います。あとは「Google Photoみたいなのに上げたくないので、プライベートクラウドがいいんじゃない?」っていう人もいると思うんですが、とやかくされたくない人はもうとことんプライベートを守りたい人です。

「そういうのって本当に傍聴されてないの?」「データを送るタイミングでちゃんと隠せてる?」とか「分析に使われていないか、本当かわからないよね」みたいな話があります。この人は何も信じられなくなっていると思ってください。

そうなるとこの人は「自分でやるしかないじゃん」って考える。

もう行動力の化身です。自分でやるんですよ。何をやるかというと、画像を送ろうとすると、サムネイルの切り出しがほしい、動画はエンコードしてほしい、暗号化したものをさらに外に出したいから自分のローカルから出るものはすべてめちゃくちゃに暗号化されたものを出したい。

そんなケースが……ないと思いますけど、この人はやるしかない。やりましょう。

暗号化されていないデータをどこかに送るみたいなことはできない。こういう場合どうするか。画像のサムネイル化にはImageMagickが使えるらしい。動画のエンコードはFFmpegでできるらしい。これを使いたいと思うんですけど、WebAssemblyでは用意されています。wasm-imagemagickですね。これを使うとImageMagickをwasmで動かせます。

ちょっとコードがぐちゃぐちゃなんですが、こんな感じになっています。シンプルに言うと、ArrayBufferでやりとりをWorkerあたりとかはするので、ArrayBufferでする処理がちょっと汚く書いてあります。

だからここはあんまり気にしなくていいです。

メインはここです。

commandというところでconvert、srcFileがあります。これはスペースで区切ってたコマンドそのものを配列にしているだけです。これでWorkerに対して指令を出すとイメージを返してくれます。

一方で、ffmpeg.jsです。

これはFFmpegをwasmとworkerで動かすようにしてくれているもので、これも簡単に説明すると、arrayBufferにしているだけです。

ここでまた先ほどのようにスペースで区切っているところをコマンドに置きます。

とりあえず、いろいろと省いてしまったのですが、サムネイルの切り取りができそうです。

暗号化を実現するAPI

じゃあ、今度は暗号化です。

Web Crypto APIというものが存在します。Web Crypto APIはもうどこでも使えるようになっています。

ここではまず鍵を作ります。crypto.subtle.generateKeyですね。まぁ、暗号化利用モードとかがあります。さらにエクスポート可能かどうかを設定して、暗号化と復号化が許可されているか。そうすると、エクスポートできます。

おすすめは、エクスポートできるようにしておいて、IndexedDBにエクスポートすると、WorkerってlocalStorageとかが使えないので、WorkerはIndexedDBが使えます。なので、IndexedDBで鍵をクライアントで共有できる。なので、おすすめです。

では、これを使ってファイルを暗号化しましょう。

結局これもWeb Crypto APIにかけられるかたち、Unit8Arrayにしているだけなので、あまりここは気にしないでください。

大事なのはここで、ここのsubtle.encryptというもので、さっきの暗号化モードと鍵で暗号化したいものを送ります。

イニシャルベクトルというのがあるんですけど、これは何かというのを簡単に説明すると、同じ鍵で同じものを暗号化したときに同じ結果になっちゃうと、暗号化しても解けちゃうんですね。

それが変わるように、毎回イニシャルベクトルが変わることによって、同じ鍵で同じものを暗号化しても別の結果になるようにしているわけです。

復号化の処理は割愛させてください。

写真・動画を暗号化してアップロードする

次のデモです。

次はファイル、で写真とか動画をアップロードするときに、暗号化して世界にバレないかたちで外に出したいみたいなケースのデモをしましょう。

ここに「pic-cube」というアプリを作っています。

ここでプラスボタンを押すことで写真を上げることができます。こんな感じで写真を選んで、写真がアップロードされます。これは実際ImageMagickでサムネイルを書き出して、暗号化されたものだけがアップロードされるような感じになっています。実際ここにデータとして現れます。

さらに「じゃあ動画はどうなの?」というのがあると思うので、MP4を上げてみようと思います。

動画はサムネイルがまだうまくいきませんが、動画をFFmpegでエンコードしてサムネイルを切り出したものだけがアップロードされます。完了と出ると動画のサムネイルが形成されます。これもスマホでできているので、PWAとしてはけっこうイカした機能になるかと思います。

Push API

では、続けていきましょう。最後はPush APIです。Push APIは、みなさん言わずと知れた、通知が出せる仕組みです。Firebase Cloud Messagingが非常にシンプルにできるので、これを使って、Push APIを試してみたいと思います。

まずはFirebaseでプロジェクトを作って、gcm_sender_idというのを用意すると使えます。

もちろんService Workerが必要です。Push通知を開いてないときでも必要なので、Service Workerが必要です。

大事なのはここで、トークンとか通知の許可を取ることってあると思うんですよ。何かというと、messagingに対してrequestPermissionって送ると、こういう画面が出てきます。よく見ますよね。「許可しますか?」というやつです。

ここでこの一連のコードを書くことによって、固有のユーザーにPushするためのトークンが手に入ります。

話がズレてしまうのですが、通知許可のダメな例があると思っていて。ページに入ってすぐ通知許可を取る例って最近増えてきていると思うんですが、これは非常に危険だと思っています。

なぜかというと、入った瞬間ってそこにどんなコンテンツがあるかもわからないのに、ユーザーが通知を許可するメリットってあんまり感じられないので、なんの気なしにブロックってしちゃった場合、もうそのドメインがブロックされることになるので、そのドメインが死ぬことに等しいです。

配慮した例でよくあるのは、「プッシュ許可お願いします」みたいなサンドボックスをこっちで用意しておいて、許可ってやってからこれが出る。まぁ、許可を押してからもう1回許可するって二度手間になるんですけど、こっちのほうがユーザーが許可してくれる率が高いです。通知が欲しそうなタイミングでやるといいなと思います。

では、Push通知をやってみましょう。

Cloud Messagingだと本当にここにPOSTするだけです。下にトークン、OauthTokenを用意して、ここでそのトークンのターゲットに対して送ることができるようになります。その下のnotificationでtitle・bodyを設定して送ります。

Service Workerでデータメッセージを取得する

では、最後の体験にいってみましょう。PWA NIGHTの前にTwitterで「データが取りたいからService Workerインストールさせて」と何人かにお願いさせてもらいました。そのデータを出させてもらいます。

今、世界中センサーで溢れかえっています。音が聞こえる。温度がわかる。湿度を感じる。それって実はスマホも一緒で、こいつもいろんなことができるんですよ。

さらにスマホは何が普通のセンサーと何が違うのかというと、だいたいオンラインです。なので、すごいセンサーを積んだものがみんなのポケットにあって、だいたいオンライン。

こいつが反旗を翻すと怖そう。まぁ、乗っ取られるとまずいのは当たり前なんですが、ウイルスに乗っ取られたら、それは怖いです。

Push APIに立ち返ってみると、QRコードを読み込むだけでService Workerを一瞬でインストールしてくれます。

もちろんこれハードル高いんですが、通知許可さえもらえるようなサービスを用意しておけば、タスクキルされてもこのスマホを動かせます。動かせるということは、通知を出せるだけじゃなくて、実はデータメッセージというものもあります。

データメッセージというのはService Worker内で処理することができるんです。「むむ」って感じですね。

型的にはこんな感じの違いがあって、右がデータメッセージです。

notificationのところがdataになっているので、こうすると通知を出さなくてもOKです。動いちゃいます。

では、Service Workerで何ができるのというと、左がクライアントのNavigatorです。

普通はこのぐらいのNavigatorでいろいろなAPIを導入してるんですが、Worker NavigatorというService Workerの中で動いているNavigatorは意外とできることが少ないです。Information、ネットワークの速度を測ってるぐらいですね。だけど、Fetch APIが動いちゃうんですよ。

Botnetのような振る舞い

では、ちょっとデモしましょう。指定したURLを叩きに行ってもらいましょう。

ここに、アクセスをしたことがある回数をカウントしています。では、協力してくれた人みんなに僕のアドレスを叩いてくれるような指令を送ります。そうするといろんなユーザーエージェントが叩いてくれる。これおもしろいですね(笑)。

これはBotnetのような振る舞いをしていると思います。

こうすると、みんなDDoS攻撃ができるようになります。URL1つ踏むだけでBotnetに参画することになります。普通Botnet、DDoSだとDistributeなのでちょっと危ないです。IPを遮断すればなんとかなるけれど、キャリア回線とWi-Fi併用しているスマートフォンってけっこうIP変わるから危なくない? というのを1つ実験しました。

1日あたりどのぐらいIPが変わってるかというと、1人あたり2.8個です。だいたい職場と家とどこかって感じです。多い人は8個とか10個くらいIPが変わってました。なので、可もなく不可もなくですが、ブロッキングとしてはけっこう面倒くさいんじゃないかと思います。

これ本当は心配じゃないって問題なんですけど、CORS policyがあって、CORS policyを守ってれば大丈夫。ただ、public APIは叩けちゃいます。あと、自分のエンドポイントはもちろん叩けるので、いい考え方をしましょう。

寝ている間にマイニングさせる

ある人がイケてるWebアプリを作りました。でも、運営していく維持費がきつい。そうなるとよくあるのは、広告まみれにします。

広告まみれにするとお金が入ります。

そこで、仮想通貨掘ってみますかという話をします。広告出したくないけれど維持費を担保したい場合、こういう条件下ではけっこういいアイデアだったりします。

ですが、ちゃんと許可を取って掘る場合でもUXが悪いケースがあります。なんでかというと、自分が好きで使ってるアプリを使ってる最中にこんな問題が起きてしまうからです。

これってユーザー離れそうですよね。

そこで、頃合いを見て掘るようにしてみます。一番使っていなくて、バッテリーも心配なくて、オンラインに接続されている状態。これってどういうときかというと、寝ているときです。寝ているときは充電しいていますし、高速なWi-Fiにつながっているのではないかと思います。

Round-Trip Timeも同じような感じで、同じようなグラフが出たので、寝ている間は高速なネットワークを利用できそうです。

ファイルを暗号化して世界中に分散させることは可能か?

最後です。また“とやかく”されたくない人が出てきました。

この人はローカルで持ってるのも不安で、むちゃくちゃ隠したいし、Service Workerっていう話を聞いちゃったからもう何されているかわからない、いつBotnetが来るかかわからない。むちゃくちゃ心配してます。

それなら、自分の持ってるファイルを暗号化して世界中にバラしましょう。

写真を世界中のスマホに散りばめて持てば、自分のローカルが消せるので、めちゃくちゃ安全になると思いました。

具体的には、もうこんな感じで分けて、ユーザーに分けて、ユーザーの鍵で暗号化します。

もう1つの考え方としては、1人が暗号化して、もう1人が暗号化して、隣の人が暗号化していってという感じでどんどん暗号化していきます。

Push APIに立ち返ると、実はPushってトークンとサーバキーがあれば誰からでも送れるので、できちゃうんですよね。

こうやって送って復号化もできますし、それが現実的かどうかという話でした。ちょっと駆け足になってしまいましたが、あとはスライドを参照してください。ありがとうございました。

(会場拍手)