Webアプリの限界を超える方法

他の投稿はこちら

- [Webアプリの限界を超える方法(セキュリティ編)](https://qiita.com/tekka/items/d9f6fd2e30c1f778b5aa)
- [ブラウザで(WebUSBもActiveXも使わずに)FeliCaリーダーを読み込む](https://qiita.com/tekka/items/537115a3d6444b9a8848)
- [ブラウザでブラウザを操作してスクレイピングを行う](https://qiita.com/tekka/items/e6e1c51fd24fa3fd2c32)
- [Webブラウザでシリアル通信を行う](https://qiita.com/tekka/items/36edc0d6e918ac2b5ab9)

# Webアプリの限界

経験豊富なwebプログラマなら、Webでは実現困難な機能を知っているでしょう。
ローカルの特定のパスに存在するファイルを自動的にアップロードしたい、
ブラウザからクローラーを起動して情報収集したい、などなど。
Webをよく知らない顧客や、技術不足のSEがそんな機能を開発しろと言い出します。
あなたは「セキュリティ上の理由から、ブラウザでそんなことは出来ない」と断ってきたことでしょう。
それ実現できます。そう、WebSocketならね。

# WebSocket

WebSocketがどのようにWebアプリの限界を突破するか、説明しましょう。
WebSocketの特徴と言えば、双方向の通信が上げられます。
しかしここでは別の特徴、クロスドメインのアクセスが許可されていることに注目します。
Webアプリはブラウザ上でWebSocketチャンネルを開き、他ドメインのアプリケーションと通信が可能です。
他ドメインとは、インターネット上に限らず、ブラウザを立ち上げている自分のマシンであるローカルホストも含まれます。
つまり、Webアプリは、ユーザーのマシンに立てたWebSocketサーバーと通信できるのです。

# 手順

手順は次の通り。

1. WebSocketサーバーを実装したネイティブアプリをユーザーが起動する
2. Webアプリをブラウザで開き、ローカルホスト上のWebSocketサーバーと接続を行う。
3. Webアプリからブラウザを通じて命令を送信し、ネイティブアプリを操作する。(またはネイティブアプリがWebアプリに情報を送信する)

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/16162/acdee170-9df0-1ef9-ca57-e33848d4221c.png)

非常にシンプルかつ自然にアプリケーション同士が統合されているのがわかるでしょう。

# パラレルハイブリッドアプリ

これまでのハイブリッドアプリは、WebViewをネイティブアプリでカプセル化することによって、ネイティブ機能を提供してきました。
これらの形態を仮にサンドボックス型とします。
サンドボックス型に対し、WebアプリとネイティブアプリがWebSocketで通信し、並行して協調動作する形態は、パラレル型と言えるでしょう。
サンドボックス型の問題点は、結局サンドボックスから提供される機能以上のことは出来ない点です。
しかしパラレル型では、Webアプリ、ネイティブアプリがそれぞれの得意分野で本領を発揮し
しかもそれがHTML5既存の技術によって自然に統合されているのです。

# 何が作れるのか

この技術によってWebアプリの可能性は大きく広がります。
基本的にPCと繋がるデバイスは全てWebアプリで使えるようになります。
例えばカメラやマイク、カードリーダーなどとWebアプリを連携させ、新たな機能を実現することが出来るでしょう。
新規開発だけでなく、既存のクラサバアプリをWebアプリにマイグレーションする際にも有用です。
既存のアプリケーションの帳票部分を切り出し、Webアプリと連携するようにすれば
既存の帳票資産をそのまま流用できるのです。
スマートフォンアプリの開発においても、Web部分は通常のWebアプリ開発を行い
各種センサー機能だけをネイティブアプリに切り出すことが可能です。
WebUSBなんていらんかったんや！

# サンプル

[サンプルはこちら](https://github.com/tekka/ParallelHybridApp)

## Q&A
### Q. ネイティブアプリのインストール＆起動に手間が掛かるのでは？
起動については、どうやって初回起動するかが問題になります。今のところ
PCの場合はスタートアップに登録
SPの場合は接続が確立できない場合は未起動と判断し、インテントのリンクを表示
が良いかと考えています。
初回起動さえクリアすれば、ネイティブアプリをバックグラウンド常駐させることで
あとはWebアプリのサイト表示時にタイムラグなく接続できます。

インストールについては
PCの場合はClickOnceなどが使えますが
SPの場合は別途インストールしてもらうしかありません。

### Q. ActiveXじゃだめなん？
ネイティブの機能にアクセスする点ではActiveXも同様に可能ですが
1. IEでしか使えない
2. セキュリティレベルを下げないと使えない
3. COMが面倒くさい
といった問題があります。
当手法では、これらの問題が全て解決されます。
(似た立ち位置にAdobeFlashがありますが、死にかけてるので割愛)

### Q. ブラウザのExtensionじゃだめなん？
ブラウザのExtensionおよびAddonは、ブラウザのサンドボックスが提供する機能以上の事が出来ません。
当手法は、ネイティブの機能に制限なくアクセスできます。

### Q. クロスドメインなら、CORS設定したHTTPサーバーを実装すればいいのでは？
実現したい機能によっては、その通りです。
ネイティブアプリからのプッシュ機能もCometなどロングポーリングによって、ある程度実現できるでしょう。
ですが、ビデオチャットやゲームコントローラの接続など、リアルタイム性が要求されるものは
オーバーヘッドの少ないWebSocketでないと厳しいかと思います。

### Q. 危険じゃないの？
ネイティブアプリのインストール＆起動については、勝手に行われず、ユーザーが自分の意図で行うため
セキュリティリスクはフリーソフトをダウンロードして起動するのと同程度でしょう。

### Q. ローカルホスト上のWebSocketにSSLで接続するための、サーバー証明書をどうやって用意するのか？
~~所有しているドメインに対して、何らかの形で正規のネームベース証明書を取得できれば
ドメインの向き先を127.0.0.1に設定することで、ローカルホストに正規のサーバー証明書を適用することが出来ます。
この方法でSSL接続を用いる場合、サーバー証明書の秘密鍵をネイティブアプリに同梱して不特定多数に配布することになります。
使用するドメインはローカルホストとの通信だけに使用し、インターネットに公開しているサーバーには絶対に使用しないでください。~~

最新のブラウザではHTTPS→HTTPローカルホストに接続しても
混在コンテンツと判定されなくなりました。
そのため、SSL証明書の処理を削除し、HTTPでWebサーバーを起動するように修正しました。

### Q. 開発者ツールで通信内容が丸見えなんだけど？
解決方法を[こちら](https://qiita.com/tekka/items/d9f6fd2e30c1f778b5aa)に投稿しました。