freedom-man.com

ブログは俺のセーブポイント

Tag: goinstant

GoInstant触ってみる【ACL編】

これまで、GoInstantのデータの取り扱いについて説明してきましたが、実際のアプリケーションでは

”このルームにはこのユーザしか入れない”とか

”この時間になったら、このルームへの入出を許そう”とか

”このデータを取得できるのはadminユーザだけ”とか

そういったアクセスコントロール要件が出てきます。

 

もちろんこういったアクセスコントロールにもGoInstantは対応しています。

ということで、今回はACLについて。

 

基本的にGoInstantではAccess ControlというJSONの設定とユーザのJWT(ユーザ名とかグループ名)によって

制御することができます。

 

例えば、RoomにJoinできるユーザを絞り込みたいときは

こんな感じにやると、localhostで発行されたtzm@freedom-man.comっていうユーザがJoinできる設定になります。

(@を%40にしないとエラーになったので、ちゃんとURLエンコードしないとダメみたい…。)

 

グループだとこんな感じ。

freedom-manっていうグループに属するユーザはJoinできるっていう設定になります。

 

一つ一つ特定のユーザ名やグループ名を設定するのは正直しんどいので、

ルームの名前が付いたグループとかユーザ名を一括で許可する設定ができます。

こうすると、ルームの名前 + “-grp”の名前(lobbyだったら”lobby-grp”)のグループに対して

一括でJoinの権限を付与することができます。

 

あるキーの読み取りを制限したい場合は以下のように書きます。

これで、localhostから発行されたtzm@freedom-man.comユーザのみtestキーの値を取得することが出来ます。

 

onメソッドのイベントも制御することができます。

こうすると、on(“set”, … と記述してもlocalhost:tzm@freedom-man.comユーザ以外では

コールバック関数が実行されることはありません。

 

これらのACLを設定して、あとはグループとユーザ名の制御をJWTで行ってあげればOKです。

python + flaskだとこんな感じ。※スクリプトタグでのJS呼び出しで対応しているのでFlaskのResponseがJSです。

 

JWTの生成にはGoInstantと共有している秘密鍵が必要で、ユーザが自分自身で生成することは不可能です。

つまりJWT生成を行うサーバサイドで、「この時間帯でこのユーザであればRoomへのJoinは禁止しよう」等の

細かい制御をすることになります。

※expire的なパラメータが無いので、使い回しはできちゃいそうですが…。

 

パーミッションでエラーになったときはこんな感じのエラーが出ます。

goinstant-permissionerror

GoInstant触ってみる【CollectionとDataLifeCycle】

今回はGoInstantのCollectionとDataLifeCycleについて!

 

Collection

GoInstantはJSONのキーバリューを動的に増やしていくような機能(add)を持ってます。

サンプル↓

addcollection

 

見ての通り、key値が自動的に生成されて、そのkeyに対して指定した値がセットされます。

addを繰り返すと、こんな感じに増えていきます。

addcollection2

 

‘/test/xxxx’っていう重複しないキーに対して値をセットすれば同様の挙動を得られますが、

自動的に重複しないキーを生成したい場合はaddを利用することになります。

 

※配列やオブジェクトの型を持つ値に対して

読み込み(get)→読み込んだデータに値を追加→書き込み(set)

というフローでもいけそうですが、トランザクションを考えると排他制御をかけないといけないし

排他制御をしたところで、リアルタイムなコミュニケーションはできなくなるので、この方法はダメ。

 

Data Life Cycle

GoInstantではデータの有効期限を設定することが出来ます。

以下のコードはセットしたデータが3秒後に削除されるサンプルです。

expiredata

 

ちなみにここで設定するexpireは、GoInstant上で保存されたタイミングから起算するため、

JavaScriptで設定してGoInstantサーバにデータが保存されるレイテンシを考えると

多少の誤差があります。(といっても秒レベル)

 

また、階層構造上、親子関係でない値であっても、キー同士を関連付けて

「ある特定のキーが削除されたら、関連するキーも削除する」といったことが可能です。

GoInstant触ってみた【Retrieving&Setting Keys編】

今回はGoInstantで一番大事(だと思ってる)なデータ部分の操作を解説してみます。

 

任意のキーの値を設定

前回同様connectでroomにJoinしてroomのメソッドで

と書くと、/testのキーに対する値を設定できます。

返り値のresultはこんな感じ↓

setkey

 

オブジェクト、数値型、配列の値も入力できます。

 

任意のキーの値を取得

こんな感じで取得できます。

 

Roomのデータの持ち方は階層構造になっていてJSONみたいな構造になっています。

1Room1JSONって感じで、”/test”のキー値が{“aaa”: “bbb”}のようなオブジェクト構造であれば

“/test/aaa”というキー値で”bbb”という値を取ってこれます。

 

また、以下のように”/”というRootのキー値を指定するとRoom内の全てのデータを取得出来ます。

allroomdata

 

キー値の設定を検知

valueは更新値、contextは誰が何を更新したか的な情報になります。

onset

 

キーの削除

 

removeの検知はkey.on(“remove”, … でOK。

キー値を削除するので、下位のキー値も全て削除されます。

また、”/.users”は削除できないっぽいです。Joinしてるからそりゃ無理ですよね…。

 

これらのキー値の取得、設定、削除、変更の検知を駆使してWebRTCを実現するのが

GoInstantアプリケーションのメインの部分になると思います。

GoInstant触ってみた【User Presence&Data編】

WebRTCサービスのGoInstant触ってみたので基本的なところを紹介してみまっす。

 

GoInstantの紹介は以下のWebサイトが詳しいです。

リアルタイムBaaS「GoInstant」の概要

 

超カンタンに言うと、GoInstantはチャットやWeb会議的なリアルタイムコミュニケーションアプリを

簡単に作るためのサービス(Baas)です。

 

GoInstantではRoomという概念があります。

これはデータ伝達範囲の単位で、GoInstantでは同一Room内でのみデータのやり取りが行われます。

GoInstantではRoomに対して各ユーザがJoin(ログイン的なもの)して、Room内のデータを操作したり

同一Roomの他のユーザがデータを更新したら、即座に画面に反映したりといったことが出来ます。

一人のユーザが複数のRoomにJoinすることもできます。

 

Room内のデータは階層構造で持っていて、JSONみたいな感じです。

JSONのプロパティに当たる部分をGoInstantではkeyと呼びます。

(むしろJSONでもkeyって呼ぶ気がするけど…)

 

概念的なことはさておき、これ以上説明するとボロが出る百聞は一見に如かずということで、

実際にコードを書いていきます!

 

GoInstantに接続(RoomにJoin)

以下のようなコードを書けばOK。

これを実行するとguestアカウント(匿名)としてデフォルトのRoomである[Lobby]にjoinします。

lobby

 

guestアカウントの表示名やJoinするRoomを指定するにはconnectメソッドの部分を

以下のように書き換えるだけ。

TestRoom

 

基本的にはこのconnectを実行した後の非同期コールバック関数の引数に入る

roomやconnectionを使って色々と操作をすることになります。

 

Room内にJoinしているユーザ一覧を取得する

connect実行後のコールバック関数のroomオブジェクトを使って

と書けばOK。

 

room.usersはroom.key(“./users”))と同じで

対象RoomにJoinしているユーザリストのkeyを取得します。

 

Object.keys(users)でusersオブジェクトのキーを全て取得してます。

arrayだったらforで回せば良いですが、ユーザ一覧としてユーザIDをプロパティとしたオブジェクトが

返ってくるため、一覧を取得するにはキー値を全て取得する必要があります。

 

 

上記の方法はPromiseを使ってます。

Promiseを使わないやり方だと、get(function(){})って感じになって

後続の処理があったりするとコールバック&ネスト地獄になるので、Promise使った方がスッキリします。

 

connectの部分もPromiseを使うと

と書き換えることができます。

 

Roomへの入退出(Join,Leave)を検知して処理する

 

検証するにはGoInstantをサポートするブラウザを2つ立ち上げて、同一RoomにJoinします。

Chromeの場合はシークレット・ウィンドウを使うと楽です。

 

入退出するとこんな感じになります。

joinGuest

leaveGuest

 

自分自身の情報を取得する

 

ちなみにGuestアカウントですが、GuestでJoinするとlocalStorageに以下のようなデータが格納されます。

JWTっぽい。

guestId_localstorage

 

あと、Guestの場合はidとかproviderとかgroupsは自動で割り振られて変更できません。

 

connectのところで以下のようにJWTを投げると、GuestではないAuthenticatedなUserでログインできます。

JWTの生成はこの記事を参考ください。

 

 

PythonとかApexでJWT作ってGoInstantにぶっこんでみる。

SalesforceがGoInstant買収してどうのこうのって話らしいので、GoInstant試してます。

 

GoInstantでユーザ認証するには外部の認証プロバイダ(facebook, salesforce, github, google, twitter)

を使ってOpenID Connectやら何やらで認証するか

自前の認証プロバイダ(と言っても普通のログイン機能を有するアプリ)で

JWTをGoInstantに投げ入れて認証します。

 

前者の場合はそれぞれのアプリケーション設定して

ClientIDとかSecretを設定してJS叩くだけで超簡単に実装できます(リファレンス)。

後者のJWT生成もGoInstantのライブラリ(Ruby、Java、PHP、node.js)があって

ライブラリのない言語の場合もJWT生成のライブラリを使えば、こちらも楽勝。

 

んで、PythonでチャレンジしようとJWT生成のライブラリをインストールしてみたけど

うまくいかなかったのでJWTの勉強がてら、自前で生成してみた。

 

 

これでJWT生成はOK。

生成の流れとしては、ヘッダ(暗号化方式を記述)とクレーム(トークンのデータ)のそれぞれのJSON文字列を

urlsafeなbase64エンコードして、それをカンマでくっつけたものを

アプリケーション毎のキーでハッシュ作ってurlsafeなbase64エンコードしてSignatureを作る。

最後にヘッダ、クレーム、Signatureをカンマで連結(それぞれbase64エンコード)して終わり。

 

実際の実装はdjangoなりflaskなりでログイン認証した後に、認証ユーザに対する適切なJWTを作って

JSの変数にバインドして、GoInstantのJSでユーザプレゼンスを得るって感じになる。

 

Apex(force.com)だとこんな感じ。

 

Salesforceの場合、ログイン認証は既にWebアプリとして持っているため

ログインユーザに見せるVFページでJWTを発行すれば、GoInstant内でもユーザプレゼンスが確保されます。

 

© 2017 freedom-man.com

Theme by Anders NorenUp ↑