見出し画像

【配布】PythonでAndroidアプリ作成してみる #12 バックアップサーバーの構築と完成

こんにちは、Rcatです。
バックアップアプリもそろそろ大詰め!今回はサーバー側の話です。
前回まででアプリはほぼ完成しましたので、今までWindowsで動かしていたサーバーを予定通りLinuxの方に入れていきます。
また、今回からvenv仮想環境やrequirementsを用意するようにします。
それと一部クライアントの修正を行いました。UrlRequestの部分でwait()とコールバックについて再考しました。

本シリーズはこちら


サーバについて

概要

まずはサーバーについておさらいです。
今回のバックアップはWebサーバーの仕組みを使用して行っています。
詳しい動作は下記の通りです。

  1. ユーザー認証
    接続される端末は1つとは限らないので、端末を見分けるといった意味での認証です。
    認証を行うとクッキーが発行され、バックアップを行う準備ができます。

  2. ファイルリストの取得
    クライアントはサーバーに対してフォルダの中にあるファイルのリストを送信します。
    サーバーはリストを見て、ファイルの有無や更新日時になどから必要なデータのみに絞りリストを返却します。

  3. データのアップロード
    クライアントは受け取った。必要ファイルリストをのデータをアップロードしていきます。
    大きなデータは分割して送信することもあります。

詳細な作りこみは下記で行っています。
※この記事ではサーバー側も多少の変更はありますので下記記事と必ずしも動作が一致するわけではありません。

Flaskの操作についてはFlaskの使い方は下記動画をご覧ください。
初期段階からファイルのアップロードまで網羅しています。

サーバを導入

実機紹介

導入するのは下記のPCです。
スペックなどはこちらの記事を参照してください。

導入

まずはLinuxサーバーにプログラムを転送します。
サーバー側では適当なフォルダを用意しておきます。この中にバックアップ用のフォルダーも作成されるので、それを念頭に置いて配置してください。

内容

次にサーバーのパッケージ内容について紹介します。

  • create.sh
    仮想環境を作成し必要ライブラリをインストールするスクリプトです。
    requirementsを使用するので、私と同じバージョンのライブラリをインストールします。
    仮想環境を使用することで、他のスクリプトの実行環境と切り離すことができます。また、ライブラリの列挙が容易にもなります。

  • start.sh
    作成した仮想環境を使用してサーバーを起動します。systemdを使う場合もこのスクリプトを指定します。
    仮想環境を使わない場合は、このスクリプトを使用することはできません。

実行

start.shを実行することでサーバーを起動できます。
アプリ側のサーバー設定にサーバーのipアドレスを指定してください
準備が整ったら、アプリ側でバックアップ開始ボタンを押すことでバックアップすることができます。

この画像は使いまわしなのでアドレスが違う

systemdを使う

Linux起動時に自動起動させるにはsystemdを使用します。
ユニットファイルの例は下記の通りです。
systemdの使い方については最初の実機紹介の記事で詳しく解説していますので確認しながら設定してください。

クライアント側修正

今回実験をするにあたり、いくつか問題があったため、クライアントの修正も行いました。

UrlRequestでtimeoutが効かない

サーバーとの接続ができなかった場合、エラーでを終了するようにしているのですが、サーバーを起動せずに実行してみたところ、いつまでたっても何も起きませんでした。
どうやら接続できない時点wait()で止まって先に進まない状態ですね。タイムアウトは5秒で設定しているので、全く何も起きないというのは不自然です。

今回のコードはコールバックを使わず、ひとつの関数内で同期的に実行するような形になっています。
どうやらこの方法だとタイムアウトがうまく機能しないようなので、コールバックを使用しようと思います。

とはいえ…コールバック地獄が嫌なので今の状態にしている訳なのでちょっと工夫します。
まずはコールバック関数の作成です。
今回、同期的に実行する関数の中にクロージャーで作成します。そしてこの関数の中で外側のフラグを操作します。
そうすることでコールバックを使用しつつコールバック地獄にもならないという設計です。

リクエストの行はこのように変更しています。
リクエスト成功のコールバックとエラーの時のコールバックを指定しています。
そして、コールバック関数内で変更するフラグを使用した無限ループを組みます。エラーになるか、正常にリクエストが通るかでこの無限ループから抜けられるわけですね。
追記:on_errorはレスポンスコード400台を表すものではなかったです。
レスポンスコード400をキャッチするにはon_failureを使います。

実行結果がこちら
サーバーを起動せずにバックアップをスタートした場合、5秒でタイムアウトし正常に終了しました。
このライブラリはコールバックが基本で、同期的な使い方は一応できる程度のスタンスのようですね。
wait()を使わずにコールバックにフラグを入れる方がいい感じはしますね。

ちなみにこの方法を取ったところ、wait()を使った時劇遅だったアップロードが標準並みにUPしました。

ログの流れる速度はこちら

wait()を使用していた激遅時代はこちら

セッションの延長

認証時にクッキーが発行されますが、有効期限が設定されており期限が切れるとサーバーがクライアントを識別できずエラーになります。
下記はサーバー側での延長処理ですがこれの反映がうまくできていなかったのでクライアントの方を修正します。

組み込むのはファイルリスト関数です。
サーバーの処理に上記の記述がある場合、レスポンスヘッダーにset-cookieのアイテムが入ります。
再取得したクッキーをグローバル領域に保持して使います。

レスポンスヘッダーの例
きちんと新クッキーが発行されています。

{'Server': 'Werkzeug/3.0.2 Python/3.10.12', 'Date': 'Wed, 01 May 2024 06:16:28 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '374', 'Vary': 'Cookie', 'Connection': 'close', 'Set-Cookie': 'session=eyJfcGVybWFuZW50Ijp0cnVlLCJjbGllbnQiOiJNYWluUEMifQ.ZjHePA.Lxvqq9Rqwg9gKdXLOyGEeR8kACw; Expires=Wed, 01 May 2024 06:21:28 GMT; HttpOnly; Path=/'}

まとめ

今回はサーバー側の運用準備を行いました。簡単なテストデータだけでなく本番のフルバックアップをしてみるとまだまだ色々問題がありクライアントも進化しました。
これにてひとまずVer1.0.0は完成でしょうか。
まだ付けたい昨日はあるので今後はアップデートという形で進めていこうと思います。
それではまたお会いしましょう。

データ配布

今回作成した全データの配布を行います。

アプリ(apk)

サイズが大きいためリンク共有をしています。
下記記事よりDiscordサーバーに参加してリンクを取得してください。

サーバーのみ

ソースは配布システムより配布しています。
入手手順や仕組みはリンク先で解説していますのでご確認ください

https://script.google.com/macros/s/AKfycbysRqb7488rvLGPqOOhGlr0w513zIHC67BEPzJtPAKrAc4lKfDCmsB0mVL1Ha5BY5P0/exec?name=kivy_Androidアプリ_バックアップ_server

全て

コンパイル済みアプリを除いたソースすべてはこちら。
また、サーバーのアップデートはこちらでのみ配布となります。
取得には最下部記述のキーワードが別途必要です。

https://script.google.com/macros/s/AKfycbysRqb7488rvLGPqOOhGlr0w513zIHC67BEPzJtPAKrAc4lKfDCmsB0mVL1Ha5BY5P0/exec?name=kivy_Androidアプリ_バックアップ_all

ここから先は

67字

¥ 300

情報が役に立ったと思えば、僅かでも投げ銭していただけるとありがたいです。