3: 2015-07-02 (木) 14:45:17 njf |
4: 2015-07-13 (月) 06:40:05 njf |
| **登録処理 [#n8d8c653] | | **登録処理 [#n8d8c653] |
| +ユーザーが新規登録を選んだ場合、サーバーで登録処理を行う | | +ユーザーが新規登録を選んだ場合、サーバーで登録処理を行う |
- | +サーバーから戻されたIDとパスワードをSharedObjectで保存する | + | +サーバーから戻されたIDとパスワードをクライアントはSharedObjectで保存する |
| | | |
| **ログイン処理 [#vfb97bf8] | | **ログイン処理 [#vfb97bf8] |
| | | |
| また、サーバー側には登録処理、ログイン処理、セーブ処理をするAPIが必要です。 | | また、サーバー側には登録処理、ログイン処理、セーブ処理をするAPIが必要です。 |
| + | |
| + | *URL構成 [#r4de93f6] |
| + | 以上のことを踏まえて、URLの構成は以下のようになります。 |
| + | |
| + | /crossdomain.xml |
| + | /api/entry |
| + | /api/save |
| + | /api/load |
| + | |
| + | crossdomain.xmlはflashを別サーバーにWebで公開するときに必要です。それ以外のアプリなどでは必要ありません。 |
| + | 上記のものは最低限必要な構成で、実際にはルート以下にfavicon.icoやrobot.txtなどいろいろと入れたくなるので、煩雑にならないようapiは別ディレクトリにまとめます。 |
| + | |
| + | URLと実ファイルの対応は別途定義できるので、実際にはapi以下のURLは1つのファイルで処理します。 |
| + | |
| + | *静的ファイルの取り扱い [#p9129989] |
| + | crossdomain.xmlのような静的ファイルはapp.yamlの中でURLと実ファイルの対応を定義します。 |
| + | 具体的には、/crossdomain.xmlにアクセスがあった場合、static/crossdomain.xmlというテキストファイルが読み込まれるようにするには、app.yamlの中で以下のように定義します。 |
| + | |
| + | - url: /crossdomain.xml |
| + | mime_type: text/xml |
| + | static_files: static/crossdomain.xml |
| + | upload: static/crossdomain.xml |
| + | |
| + | 他にもいろいろな割り振り方がありますが、ゲーム保存用のAPIサーバーには静的ファイルはあまりないはずなので、これだけ覚えておけば十分かと思います。GAEでも静的ファイルは取り扱えますが、大量にある場合はそれを置くために通常のWebサーバーを用意した方が便利で安くつきます。 |
| | | |
| *フレームワークの導入 [#w185f5fa] | | *フレームワークの導入 [#w185f5fa] |
| | | |
| これを使って前回の記事で作ったHello Worldを作り直すと以下のようになります。 | | これを使って前回の記事で作ったHello Worldを作り直すと以下のようになります。 |
| + | まず、app.yamlです。 |
| + | |
| + | application: hello-world-app |
| + | version: 1 |
| + | runtime: python |
| + | api_version: 1 |
| + | |
| + | handlers: |
| + | - url: /.* |
| + | script: helloworld.application |
| + | |
| + | ここで大きく変わったのはscriptのところがファイル名では無く、ファイル名+「.」+変数名となっているところです。これに対応したhelloworld.pyは |
| + | |
| + | import webapp2 |
| + | |
| + | class HelloWorld(webapp2.RequestHandler): |
| + | def get(self): |
| + | self.response.headers['Content-Type'] = "text/plain; charset=utf-8" |
| + | self.response.write("Hello, world!") |
| + | |
| + | application = webapp2.WSGIApplication( |
| + | [('/', HelloWorld), |
| + | ], |
| + | debug=True) |
| + | |
| + | となります。app.yamlでhelloworld.applicationと指定したせいで、helloworld.py内のapplicationというオブジェクトが呼び出されることになります。そのオブジェクトの中で"/"にはHelloWorldクラスを対応させているので、ルートへのアクセスに対して、HelloWorldクラスの処理が呼び出されます。 |
| + | |
| + | HelloWorldクラスにはgetメソッドが定義してあり、GETリクエストに対してはこれが呼び出されることになります。もちろんpostメソッドを定義することも可能です。 |
| + | |
| + | getメソッドの中は単にヘッダと本文をクライアント向けに書き出しているだけです。 |
| + | |
| + | 元のHello Worldのサンプルに比べて複雑になったように見えますが、GETやPOST、ヘッダーの指定などをフレームワークでやってくれる上に、最後のapplicationの定義を変えていけばapp.yamlを変更せずにURLと処理の対応を変更していけるので、ある程度規模が大きくなるとこちらのやり方の方がずっと楽になります。 |
| + | |
| + | *GAEのデータ保存 [#v7706534] |
| + | |
| + | GAEではデータはBigtableというものに保存されます。通常のリレーショナルデータベースに似ていますが、集計や表の結合などは自分でスクリプトを書かないと基本的には出来ません。1レコードごとに検索のためのキーがついているだけのデータの集まりの様な物で、どちらかというとファイルに近いかも知れません。公式ではリレーショナルデータベースと区別するためか1データの事をエンティティと呼んでいます。リレーショナルデータベースに慣れている人には分かりづらいと思うので、このWikiでは基本的にデータはレコードと呼んでいます。他の資料に当たるときには注意してください。 |
| + | |
| + | カジュアルゲームのデータ保存の場合、集計や表結合は普通無いのであまり問題ないと思います。しかし、ランキングだけはちょっと面倒です。これについては別途機会を設けて解説する予定です。 |
| + | |
| + | また、GAEはデータの排他処理があまり得意ではありません。同時に1つのデータに大量にアクセスするような、たとえばアクセスカウンターのような物だとエラーが出る場合があります。これを回避する方法もまた別途解説する予定です。ただ、こちらもカジュアルゲームではそれほど使わないと思うのでさほど問題では無いでしょう。 |
| + | |
| + | 一方、リレーショナルデータベースと違って、後からテーブルの列を加えたりするのは簡単にできます。また、データが分散されていて互いにバックアップされているので、サーバーの不具合でテーブルまるごと消えたりすることはまずありません。テーブルのサイズにも制限はありません。 |
| | | |
| 準備中 | | 準備中 |