React Native製Mastodonクライアント「ikuradon」をgithubで公開しました。

potproject/ikuradon

React Nativeの勉強のためにちまちまと作ってたアプリなのですが、

最近、せっかくなので何かOSSとして公開したいなーと思っていたので公開します。アプリ名も安直です。

React Native、色々言われてる割には国内でのちゃんとしたアプリのソース公開も少ないので、参考になればいいんですけども。

内部のライブラリにReact Redux,React Navigationを使用しています。

Reduxは覚えるのに苦労しつつ、この実装でいいのか今もイマイチな感じがあるのですが、全体のデータを管理出来るので、Reduxか似たようなものが無いと設計段階でやはりキツいです。

まだまだ開発途中で、一部遷移が遅かったり、そもそも動かなかったりしますが、そこはちゃんと整備します。デザインも変えていくので許して。

とりあえず今のところはタイムライン表示機能とfav,boost,普通のTootとまあ本当に最低限の機能という感じ。

開発期間は割と短いし、Androidでは一切検証してなかったけど大体普通に動きます(バグあるけど)。

React Native(というかExpo)開発に関して

とりあえず、Expoが本当にすごい。

コード更新即反映即立ち上げのHot Reload機能、その他役に立つ解析機能やAPIなどかなり開発速度を早くできたのもこのおかげです。

そしてWindowsでも実機でiOSネイティブ開発出来ちゃいます。わざわざ埃被ってるMacBookを出さなくていいです。

ネックなのはデバッグモードがかなり遅いところですねえ。そのせいで本番と挙動が違う部分も出てきたりします。
この部分はアップデートとProduction Modeが追加されてかなりマシになったと思います。でもネイティブビルドと比べると遅いけどそれはしょうがない。

速度的には充分ネイティブ並みに動いてると感じます。UI自体はネイティブですし、よくあるUI部分を同期的に書いてフリーズする、みたいなことも基本無くてよろしい。
デフォルトでES6とES7の一部分をサポートとしており、JS界隈でありがちな「初期の構築いろいろあり過ぎて辛い」もなく、await/asyncが使えるのは非常に便利です。

開発は楽で楽しいんですけど=簡単に作れるってわけではないと思います。そもそもReactやRedux、ES6の知識が必要ですし。

WebSocketもデフォルトでサポートされていたので、Streaming APIの対応もすんなりいきました。100行程度でいけます。強いです。

動かし方

上でも書いたとおり、Expoというアプリを使用します。このアプリをダウンロードして、このCDNリンクからQRコードを読み込むだけ。

開発なら、cloneした後npm installからnpm startでQRコードが出てきます。これで終わり。後は同じ。

自分もこれで実機のiOSで開発しています。ほぼnpmで事足りるのでホームページからわざわざSDKダウンロードしたりすることも無し。なんともモダンって感じの開発環境です。

App StoreやGoogle Playの公開はもうちょっとできてから考えようって感じです。

また、時間があれば開発での辛いところとか書いていきます。

React Nativeのルーティングライブラリ比較

ルーティング(Router)ライブラリとは、画面遷移や戻る、進むなどを行うライブラリのことです。

WebではSPAのページを作成するときに必要なため、SPAでなければ使用することも無いと思いますが、

React Native単体ではルーター機能はほぼ無いに等しく、現在のバージョンではNavigatorIOSというAPIしかありません。

名前が示す通り、Androidでは使用できないため、これは使えません。

画面遷移を含まないアプリなんてまず無いと思いますので、RNアプリ作成するにはRouterライブラリは必須です。

RNで使用できるルーティングライブラリの上位3つを比較してみました。

主にこの3つがメインかなと思います。

一応、アプリ開発で全て触ってます。上から順に使っていった感じです。

そして、最終的にReact Navigationに落ち着きましたという記事です。

React Native Navigation

wix/react-native-navigation

★Star 4300 NativeModule使用

App-wide support for 100% native navigation with an easy cross-platform interface.

利点:

  • ネイティブの処理で遷移するため、速い。そのため、デザインもネイティブベースである。

欠点:

  • ネイティブモジュールを使用しているため、Expoを使用できない
  • ネイティブで動作するため、カスタマイズ性は低い

個人的に:
Reduxサポートはしているみたいだが、公式のredux-exampleがdeprecatedだったり、イマイチ書き方がわからなかった。ちょっとドキュメントが整備されていない?

AndroidとiOSでの表示のプレビューなどもないため、よくわからなかったという感じでした。

一番速度的には速いと思うのだが、Expoで開発したいというのもあるため、非採用

React Native Router

aksonov/react-native-router-flux

★Star 5200

First Declarative React Native Router

利点:

  • カスタマイズ性が高く作られている。NavBar/TabBar部分に独自のcomponentsを表示できる
  • react-routerライクで作られているため、使ったことのある人は入りやすい

欠点:

  • 独自な分、NavBar/TabBarっぽいデザインが用意されていない。デザインを作って指定する必要がある

個人的に:

たとえば公式APIにTabBarIOSがあるが、Androidには存在しない
そのため、iOSとAndroidでTabのデザインを分けるか、独自でデザインを作る必要が出てくる、それはやりたくないため見送り。

※ここで話しているのはv3の話です。v4ではReact Navigationがベースにカスタマイズ出来るよという感じらしいので、

デザインはReact Navigationと同じようなものが使えると思います。
v4が正式になったら、こっちのほうを採用したかも・・・

React Navigation

react-community/react-navigation

★Star 6400

Learn once, navigate anywhere.

利点:

  • ネイティブっぽいデザインがデフォルトであり、少ないコードで割とすぐにそれっぽく作れる。
  • AndroidとiOSでiOSはTabbar、AndroidはTabLayoutっぽいデザインになる。
  • Star数も一番多い。ドキュメントが豊富

欠点:

  • rnrfよりはカスタマイズ性は劣る。わかりやすいけどtitleをComponentsのstaticで指定する部分とか一部トリッキーだったりもする。

個人的に:

React Community製のライブラリ。
一番ドキュメントが充実しており、同じようにReact Community製のReduxサポートが充実していてわかりやすかった。

ネイティブっぽいデザインがデフォルトで表示され、開発しやすい。

rnrfよりはカスタマイズ性は劣るが、ネイティブっぽい表示が目的だったため現在これで開発中。

  • 動作速度重視ならReact Native Navigation
  • カスタマイズ性重視ならReact Native Router
  • 開発速度重視ならReact Navigation

という感じで、うまいこと差別化ができていると思います。

一番困るのは非常に名前が紛らわしい点でした。特にnpmは似たような名前のスパムすらあるから困る。

(今作ってるRNアプリはOSSとして公開するつもり。明日。頑張ろう。)

HTTP/2とTLSv1.3(draft-20)をnginx+OpenSSLで対応させる

せっかくなので、当サイトはhttp2に正式対応しました。

昔やったはずじゃ・・・と思っていたのですが、

http/2と似て非なるほぼ同じSPDYの対応でした。

SPDYはいつの間にやらchromeではhttp/2扱いされなくなり(googleが作ったのに)、chrome 51から非対応となってしまいました。

ということでこのブログもhttp1.1に戻っていたので、正式にhttp/2に対応しました。
この辺は別の話なのでこの記事が詳しいです。

EC2+nginxでhttp2対応できたとおもったらできてなかった話。(解決します)

ついでに、当サイトはTLSv1.3(draft-20)に対応しました(多分)。

なお、言っておきますが 現状のブラウザでは見れません。

新しくブラウザが出たとしても見れるかもわかりません。

正直まだstandardになってないですし、仕様は変更されるでしょうし、現状ここでの対応はほぼ無意味です。

ただ、TLSv1.3が正式対応になりOpenSSL1.1.1が正式リリースした時はこの記事は役立つと思います。多分。

OpenSSLのTLS1.3実装に関しては公式が使用方法を書いています。これがとても詳しいです。
Using TLS1.3 With OpenSSL

コネクションの方法など難しいところは置いておくとして、
実際に使用するところで気になるのは暗号化スイートがTLS1.3専用のものが用意されています。

  • TLS13-AES-256-GCM-SHA384
  • TLS13-CHACHA20-POLY1305-SHA256
  • TLS13-AES-128-GCM-SHA256
  • TLS13-AES-128-CCM-8-SHA256
  • TLS13-AES-128-CCM-SHA256

OpenSSLの現在の実装でTLS1.3はこの5つしかサポートされていません。

これ以外を使用してTLSv1.3認証を行おうとすると、当然ですが認証に失敗します。

そのためTLS1.2以下と併用するためにはTLS1.3の時だけ上のスイートを優先する必要があります。

nginx+OpenSSLでのTLSv1.3対応

nginxのmailline versionの最新版1.13.0にて、"ssl_protocols" でTLSv1.3を選択できるようになりました。

*) Feature: the "TLSv1.3" parameter of the "ssl_protocols" directive.

そのため、おなじみの構成であるnginx+OpenSSLでTLSv1.3を使えるようになります(厳密にはなる予定です)。

使用するnginxは1.13.0、OpenSSLは1.1.1-dev(master)です。

OpenSSLはTLSv1.3が正式になったら1.1.1をリリースすると言っていますので、実際に正式になった時もこの設定で動くと思います。

OpenSSL1.1.1(dev)のインストール

リポジトリなどではなくgitからmasterを落としてビルドします。gccなどが必要です。

後、libssl.soが無いと怒られたりしたので/usr/local/lib64/に動的リンクを貼ったりpathを通したりして動きました。

cd /usr/local/src/
git clone https://github.com/openssl/openssl
cd openssl
./config enable-tls1_3
make
make test
make install

/usr/local/bin/openssl version
OpenSSL 1.1.1-dev  xx XXX xxxx

nginx 1.13.0のインストール

こちらはリポジトリはあるのですが、OpenSSLを組み込む関係でこちらもソースコードからビルドが必要です。

このやり方だとyumなどで本体に入っているnginxは削除しました。

configureのオプションは各自吟味してください。

cd /usr/local/src/
wget http://nginx.org/download/nginx-1.13.0.tar.gz
tar zxvf nginx-1.13.0.tar.gz
cd nginx-1.13.0
./configure --prefix=/etc/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3
make
make install

ここで重要なのは--with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3です。
–with-opensslは先ほどのopensslのソースコードのpathです。nginxにバンドルします。

–with-http_v2_moduleはhttp/2対応のため、–with-openssl-opt=enable-tls1_3も設定しないと動きませんでした。

なので使うだけならOpenSSL1.1.1(dev)をmake installする必要ないのですが、openssl s_clientを使用するために使います。

あとはpathを通して、nginx -V で確認します。うまくいけば下のようになっているはずです。

nginx version: nginx/1.13.0
built by gcc <略>
built with OpenSSL 1.1.1-dev  xx XXX xxxx
TLS SNI support enabled
configure arguments: <略> --with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3

nginx設定

既にSSL設定が終わっているなら、このあたりの設定を変更するとOKです。再起動も忘れずに。

ssl.conf

#TLSv1.3用設定
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:ECDHE:!COMPLEMENTOFDEFAULT';

#http2用設定
listen 443 ssl http2

SSLv1.3の接続確認

最初に言ったようにブラウザだと確認できませんでした・・・draft-18のものはchromeのchrome://flags/でTLS1.3を指定すると見れます。

https://tls13.crypto.mozilla.org/

このサイトを見るとdraft-18対応済みのchrome/firefoxでは正常に確認でき、TLS1.3と表示されているのがわかります。

対応していないとchromeでは「サポートされていないプロトコルが使用されています」というレアな画面が出ます。

OpenSSLのSSL/TLS client機能で接続確認します。1.1.1は-tls1_3オプションでTLSv1.3で接続しに行きます。
一部省略。

>openssl s_client -connect blog.potproject.net:443 -tls1_3
CONNECTED(00000003)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:CN = potproject.net
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate

subject=CN = potproject.net

issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 3026 bytes and written 270 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS13-AES-128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS13-AES-128-GCM-SHA256
    Session-ID:
    Session-ID-ctx:
    Master-Key: <master-key>
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: <StartTime>
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: no
---

これで正しいのかイマイチわかりませんが、TLS1.3認証は出来ていることが確認できます。

TLSv1.3の正式に決まるまでもう日は近いと思うので、その時にすぐに対応できればいいな・・・

小規模Mastodonインスタンスを運用するコツ

補足:ドキュメント移行によりリンク変更と、tasksに関しての追記を行いました。

最近は、twitterクローンであり分散型のSNSであるMastodonが勢力を伸ばしてきているところであり、自分もハマりつつあります。

実際に運用してみてわかった、大規模Mastodonインスタンスを運用するコツとしてpixiv.netが運営しているサーバpawoo.netでは、現時点で6万人以上のユーザ数を誇るほどの規模です。

その一方で、サーバ自体はオープンソースのため、誰でも立てることができ、立てたサーバはインスタンスとして他のサーバとつながることが出来ます。

実際に私も2,3日程運用して、おひとりさまで運用しております。その時のコツというレベルでもないですが、
これから構築する人に向けてはまりそうな点などをまとめておきます。

https://mastodon.potproject.net/@potpro

では、大規模に対してここでいう小規模とは何か、というと
・主に使用ユーザは1~100人程度を想定
・気軽に構築するため、公式のDockerを使用して構築
・SSLは無料のもの(Let’s Encrypt)を使用する
・サーバはVPS、月1000円~2000円程度
そして、
・ちょっとくらいのダウンは問題なし、データは出来るだけふっ飛ばさないようにする

とします。

VPSとコストに関して

基本的に小規模で運用している方々を見るに、

さくらVPSの1GB(972円/月)やAmazon EC2(従量課金、無料枠あり)が多いと思います。

私はコスパ重視で、お名前.com VPS メモリ 2GBプラン(1,099円/月、年払い)を使用しています。

メモリ2GBと仮想3コアあれば一人でロードアベレージは通常時0.1以下です。1-10人程度であればメモリ1GB以上の好きなVPSを選べばいいと思います。

自宅で管理したいなら、自宅鯖を構築するのも手ですが、固定IPアドレスの問題や安定稼働(停電で使えなくなるとか)を考えなくてはならないため、

その点ではVPSの方が優れているでしょう。

このレベルでどのくらい運用できるのかはまあやっぱり実際に試してみないとわかりませんが、100ユーザくらいなら多分大丈夫(と思いたい。

この部分に関しては公式ドキュメントのResources-needed.mdが参考になります。まだ3つしか参考がありませんが、多分増えていくと思います。
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Resources-needed.md

この記事はあくまで小規模が目的のため、ユーザ1000くらいを目指すなら、
脱Docker、PostgreSQLやRedisの別サーバー管理、Sidekiq threadsの増加、nginxのチューニング、ロードバランスなどが必要になってきますので、
その部分は他の誰かが解説してくれることでしょう。

Dockerコンテナの作成と構築

基本的に、公式DocumentのDocker Guideを読んで作成してください。
更新が激しいので、ここでは構築方法は解説しません。
何故なら構築方法が変更され、この記事の情報が古くなる可能性が高いからです。

自分がハマった点は、必ず公開用に立てるのであれば、タグ付きのリリース版を使用してください。
https://github.com/tootsuite/mastodon/releases
単純にgit cloneをしてクローンした最新のmasterブランチはうまく動作しない可能性が高いです。
タグ付きのreleaseブランチは、このようなコマンドでチェックアウトできます。

git clone https://github.com/tootsuite/mastodon.git
cd mastodon
git checkout $(git tag | tail -n 1)

アップデート

アップデートも余計なことはせず、公式ドキュメントのDocker Guide – updatingを見て行ってください。
公式DocumentにあるThings to look out for when upgrading Mastodon(Mastodonをアップデートするときの注意点)に記載されていることも重要なので参考にしましょう。
ミスったらデータ消えたり上手く動かなくなるのでここは慎重に。
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md#things-to-look-out-for-when-upgrading-mastodon

このアップデート手順通りに行えば、すぐに新しくコンテナが立ち上がることでダウンタイムも数秒で済みますし、
まず失敗することはないと思われます。

しかし、万が一の時を含め、バックアップとデータ永続化は行っておきましょう。

データ永続化

一部のデータをホストOS側にマウントすることで、コンテナを誤って削除してもデータが保持される状態にします。
docker-compose.ymlの最初のコメントアウト部分を外すことで、ホストOS側のディレクトリに保存されます。
左側がホストOSのパスとなっているので、変更すれば好きな部分におけます。

version: '2'
services:

  db:
    restart: always
    image: postgres:alpine
### Uncomment to enable DB persistance
    volumes:
      - ./postgres:/var/lib/postgresql/data

  redis:
    restart: always
    image: redis:alpine
### Uncomment to enable REDIS persistance
    volumes:
      - ./redis:/data
(略)

この作業を忘れたまま本番稼働させてしまった場合は、次で紹介するdocker cpコマンドでバックアップを取り、
バックアップをマウントするディレクトリと同じ場所に置き、アップデートを行ってください。

バックアップ

小規模といえど、データのバックアップは行いたいです。

#データベース
PostgreSQLコンテナ : /var/lib/postgresql/data
#キャッシュデータ
Redisコンテナ : /data
#取得した画像等のデータ
Mastodon-webコンテナ :  /mastodon/public/system
#sidekiqデータ
sidekiqコンテナ :  /mastodon/public/system

この4つが基本的なバックアップ対象のデータです。
一番重要なのはデータベースですが、
現バージョンでは、取得した画像等のデータも一度紛失すると再取得を行ってくれず、
タイムラインに取得済みのアバター画像が何も表示されない悲しい状態に陥ってしまいます。

Dockerの場合、Docker cpコマンドを使用することでDockerコンテナからホストOSにコピーが出来ます。
例として、

docker cp mastodon_db_1:/var/lib/postgresql/data /mastodon_data/postgresql

という形です。
mastodon_dataディレクトリにpostgresqlデータが入っていることが確認できると思います。

その他、構築時に使用した.env.productionファイルも無くした場合は再構築が簡単ではなくなるため、バックアップしておいてください。
無くしてしまった場合は、稼働しているMastodon-webサーバから
docker exec -it mastodon_web_1 env
から取得することは一応可能です。

SSL対応

Mastodonサーバでは、SSLの対応はほぼ必須です。

一応httpでも動作しますが、httpとhttpsは共存できないため、httpsのサーバからリモートフォローすることが出来ない、などの弊害があるようです。

今ではLet’s encryptなどを使用してSSL対応は簡単にできるので、個人でも敷居はかなり下がっていると思います。

公式のProduction Guideでは、nginxをリバースプロキシにして、動作することが推奨されています。
公式のProduction Guideをメインに、SSLの設定は自分の過去の記事あたりにその辺は結構書いているので、よければ参考にしてください。

Centos+nginxでLet’s encrypt(certbot)導入と自動更新まで

証明書は期限が切れると使えなくなり、アクセスしてもエラーが出て正常に使えないため、Let’s Encryptを使う場合は自動更新の設定を行うこともおすすめします。

また、公式ではssl_protocols TLSv1.2;になっているため、ちょっと古いブラウザなどで使用できない可能性もあります。
使うべきではないとされているSSLv3を除いて、広く対応を行いたければ、ssl_protocols TLSv1 TLSv1.1 TLSv1.2;に変更することをお勧めします。

Cronjobs

運用するにつれ、他のインスタンスからデータを持ってきて表示するため、放置しているとデータはどんどん溜まっていきます。
それを解消するため、公式で要らないデータ等を削除できるRakeタスクが用意されています。
※特にmastodon:dailyタスクにはPuSHの購読更新処理が含まれるため、外部インスタンスから自分のトゥートが見えなくなる可能性があります。
自分も更新しなくても大丈夫だと思っていたのですが、mastodon:dailyに関しては必ず1日に1回は動かしてください(多くてもOK)。

https://github.com/tootsuite/mastodon/blob/master/lib/tasks/mastodon.rake

#いらないやつもろもろを消してくれるタスク(日一で動作)
0 3 * * * cd /var/www/mastodon && docker-compose run --rm web rake mastodon:daily
#1週間以上前の画像動画キャッシュを削除(週一で動作)
0 3 * * 1 cd /var/www/mastodon && docker-compose run --rm web rake mastodon:media:remove_remote

自分はこのようにしてcrontabで動作させています。

swapの設定

Mastodonに限らないことですがメモリが少なくなっても賄えるようにswapを設定しましょう。
swapがあれば仮想メモリとして退避することができ、遅くはなりますが少ないメモリでもリソースが確保できます。
Mastodonは1ユーザでもそこそこメモリを食います。最低でも1GB、よくて2GBはほしいところです。

特に上に書いているmastodon:dailyタスクは、動作するだけでかなりのメモリを食います。自分もメモリ不足ギリギリ回避な感じでした。

メモリ1GBの場合は3GB、2GBの場合はswapは2GB確保と合計4GBは確保しておけばととりあえず大丈夫と思います。
(Linuxディストリビューションでコマンドが違ったりします。これはcentos7の参考例です。)

//2GB確保、当然ストレージに2GB空きが無いと作れません
if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

まとめ

Mastodonを個人で運用するメリットとして、
・データを勝手に改ざんされたり削除される心配はない
・逆に自分の好きなようにデータを弄れる
・おひとり様サーバならサーバ負担に悩まされることもない(htmlのレスポンスは100ms以下!)
・SNSを運用してるって、なんかカッコいいじゃん。自分だけの空間にするもよし、鯖管で皆を導くのもよし。

という点があり、自分もかなり満足して使っています。

私は個人的にMastodonで個人鯖を立てる人を応援しております。もっとたくさん増えて、個人鯖連合を作ろう。

Facebook PHP SDK v3.2.3でGraph API のバージョンを変更する

今回はいつもと趣向を変えた、バッドノウハウです。

Facebook PHP SDK v3.2.3は、名前の通りFacebookのGraph APIを叩くためのSDKですが、
2015年1月の時点でdeprecated(非推奨)となっております。2年前です。

非推奨というだけで今までは使用できたのですが、このSDKはGraph APIv2.2を使用しているため、利用期限が過ぎ、完全にこのままでは使えなくなりました。

使用期限:2017年3月25日

https://developers.facebook.com/docs/apps/changelog?locale=ja_JP

なので、現在推奨されているFacebook SDK for PHP (v5)を使用しましょう。

で、本来はそこで終了なのですが、実際はそうもいかない人たちもいるようで・・・
Facebook SDK for PHP (v5)はPHP5.3非対応のため、PHP5.3の場合は、このSDKを使用しているところもあります。
PHPバージョンのシェア率を見ると、PHP5.3以下はまだ 25% も存在するようです。
自分もその被害者のため、完全にバッドノウハウなわけですが、対応方法を書いておきます。

この方法で、最新バージョンのv2.8まで動作しました。しかし、完全に動作するとは思わないほうがいいです。
何時使えなくなるかもわからない綱渡り的な状態であり、応急処置みたいなものなので、早いところPHPのバージョンを上げましょう。

参考:facebook graph api not work from 2.2 to 2.3
http://stackoverflow.com/questions/42994019/facebook-graph-api-not-work-from-2-2-to-2-3

まず、バージョンを変更します。デフォルトではv2.2を使用するようになっていますが、そこを明示的に指定することで、バージョンを指定することが出来ます。
v2.8であれば/v2.8/という風にURLを変更します。v2.3にしたほうが無難だと思います。

facebook-php-sdk/src/base_facebook.php 164行目付近

  public static $DOMAIN_MAP = array(
    'api'         => 'https://api.facebook.com/v2.8/',
    'api_video'   => 'https://api-video.facebook.com/v2.8/',
    'api_read'    => 'https://api-read.facebook.com/v2.8/',
    'graph'       => 'https://graph.facebook.com/v2.8/',
    'graph_video' => 'https://graph-video.facebook.com/v2.8/',
    'www'         => 'https://www.facebook.com/v2.8/',
  );

これだけでは動きません。Graph API v2.3から、アクセストークンを取得した時の振る舞いが変更され、配列からjsonを返すように変更されたためです。
そのため、返ってきたjsonをArrayに変換することで動くようにします。
2箇所同じような部分があるので、そこも同じように変更します。両方変更しないとユーザアクセストークンなどが取得できなかったりします。

facebook-php-sdk/src/base_facebook.php 413行目
facebook-php-sdk/src/base_facebook.php 808行目

    $response_params = array();
    parse_str($access_token_response, $response_params);

この部分を以下のように変更します。

    //$response_params = array();
    $response_params = json_decode($access_token_response, true);

これでとりあえずは指定したGraph APIで動作するようになります(v2.3,v2.8以外未確認です)。
OAuthログイン、/me/、/me/account/、/feed/などは動作確認済みです。

もう一度言いますが、PHP5.4以上の方はFacebook SDK for PHP (v5)を使用しましょう。

MySQL WorkBenchでデータベースのモデルを作る

potproject.net Advent Calendar 201615日目の記事です。

今回はかなり珍しいけれど、データベースの話です。


うまいことE-R図が書ける書けるソフトウェアを探していて、
普段MySQLサーバーを操作するときに使用していたMySQL Workbenchに、
モデル作成機能があるとわかり、使ってみたらかなり使いやすく便利だったのでブログでの紹介です。

MySQL Workbenchは、MySQLに関する統合管理ソフトウェアです。Windows/Mac/Linuxのマルチプラットフォームかつ、無償です。
MySQLの開発元であるOracleが開発しています。

大体はデータベースを管理していろいろ情報を見たり、挿入したり削除したりがGUIで出来るのでそれだけでかなり便利なんですが、
モデル作成機能もついてるようです。
バージョンは6.3.8です。

ダイアグラムを立ち上げる

File -> New Model で、新しいモデルを作ります。
その後、 Add Diagram をクリックするともうE-R図の作成画面が出てきます。

基本的に、書くだけだったらそんなに難しくないです。左側のタブの真ん中あたりにあるのがテーブル追加ボタン。これでテーブルを追加。
左側にあるのはテンプレートです。ここをクリックすることで用意されたテンプレートを使用できます。
今回は一から作らず、このテンプレートを使って簡単にいきます。
userテーブル、categoryテーブルが出来ました。

テーブルを編集する

テーブルはダブルクリックすることで編集が出来ます。
テンプレートはカラムのデータ型が設定されてないようなので、編集して設定します。
主キーやデータ型などを付け加えるとこんな感じです。

関係(リレーション)を設定

E-R図なので、外部キーなどの関係を設定します。
編集状態で、 Foreign keys を選び、外部キーの名前、参照するテーブル、参照するカラムなどを設定。
今回はuser.usernameを参照するようにcategory.nameに外部キー制約を設定します。

このような感じになります。また、自動的に指定された表記法で関係が表されます。
初期状態だとIE (Information Engineering)記法となっています。自分は一番なじみのあるUML記法で表示するため、
Model -> Relationship Notation で、UMLを指定。記法が変えられるというのもかなり嬉しいポイントじゃないでしょうか。

SQLで出力

モデル機能も優秀ですが、MySQL Workbenchは作ったモデルをSQLで出力することが出来る機能があり、これが本当に使えます。
E-R図を見ながらSQLを組み立てていく時間が削減されるので、すごく便利。

File -> Export -> Forward Engineer SQL CREATE Script を選択。
途中何を出力するか聞かれるので、 Export MySQL Table Objects にチェック。
他にもViewやroleまで出力できるようです。すげー。

CREATE TABLE IF NOT EXISTS `mydb`.`user` (
  `username` VARCHAR(20) NOT NULL,
  `email` VARCHAR(255) NULL,
  `password` CHAR(64) NOT NULL,
  `create_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`username`));

CREATE TABLE IF NOT EXISTS `mydb`.`category` (
  `category_id` INT NOT NULL,
  `name` VARCHAR(20) NOT NULL,
  PRIMARY KEY (`category_id`),
  INDEX `name_idx` (`name` ASC),
  CONSTRAINT `name`
    FOREIGN KEY (`name`)
    REFERENCES `mydb`.`user` (`username`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

組みあがったSQL文がこれ。SQL文全く分からなくてもいけるわけですよ。
自分はこれくらいならSQLを書けないことはないですが、外部キーやインデックスなどまで含めて書くとなると、ちょっときつい。というかめんどくさい。
後はこれをSQLにインポートで完了ですよ。

データベースメインのひとでもかなり使えるのでは?自分は多すぎて全容把握できてないです。
欠点は、MySQL Workbenchがすぐクラッシュするくらいですね。本当に多いのよね。自動保存機能はあるらしいけれど。
まあ、なんでもそうですが、こういったソフトウェアは定期的に保存っすなあ。

GTX1060を買いました

potproject.net Advent Calendar 201614日目の記事です。

もはや普通のレビューである。


今年の冬にめちゃくちゃいろいろ買いそろえている感じ。

今度は、ついにグラボを買い換えに走りました。
ZOTAC GeForce GTX 1060 6GB Single Fanです。

この機種はファンが1つのみ、その分小さくてコンパクトというウリです。
でもやはり、ファンが1つだけという都合上、結構熱いです。
最近ハマっているtom clancy’s the Divisionでフル稼働にて70-76度というところで80度はギリギリ超えない。
でもこれでも問題ないレベルなんでしょうね。ファンは100%回っていませんし。
元々のGTX660と比べてもほとんど同じくらいでしたし。でも夏はちょっと厳しいのかも。
これでスペック不足を感じてくる日は何時になることやら。やっぱりVRに備えたというのもあるんで・・・

・・・VRもほしいんだけどなー値段がなー・・・

おまけでFire タブレット 8GBを買いました。最終日サイバーマンデーにて3500円。この値段なら損はしない。
お遊びで使ってみます。