チャットアプリを作ってみた

<追記>
Webアプリのデプロイができました！
Web: https://towelman.server-on.net/web/login

<追記 2021/7/18>
Windowsアプリができました
インストローラー https://github.com/TowelMan-public/chat-winForm/blob/main/Installer.zip
環境: .NET Framework 4.7.2

<追記 2021/8/14>
Androidアプリができました
apkファイル https://github.com/TowelMan-public/chat-android/blob/main/release/app-release.apk
環境: APIレベル 21～30対象

# 動機
 ある日突然「LINE」みたいなやつを簡単にしたやつを無性に作りたくなり、それで開発してみたくなった。

# 大雑把な機能
 「LINE」と同じように「友達」として登録した相手とチャットができ、「グループ」でも出来る。また、「グループ」にユーザーを加入させる方法は「LINE」と異なり、後述する「ユーザーID名」というやつを指定するのみである。

# ネット構成
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1597746/2e409b75-0f25-df4f-ac1f-d2ed3563ab73.png)

※尚、APIサーバとクライアントアプリが通信するときは、https通信で、18081番ポートで通信をする。httpボディーはJSONでやり取りをする。

# ER図
![ER図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1597746/9a2b67a2-7a8f-b101-3499-880473aeff20.png)


# 認証方法
### ログイン時
APIについては後述するが、ログインをするAPIを使って、「ユーザーID名」とパスワード（暗号化なし）を送って、ログイン後に使う認証用JWTを受け取る。

### ログイン後
APIに、ログイン時に取得した認証用JWTをhttpのヘッダーの「X-AUTH-TOKEN」にセットしてそのまま送る。

### その他
ログイン後（認証用JWT発効後）１時間で無効化し、再ログインを求められる。（正確にはログインしていない扱いされる）

# サーバ側
Spring Boot で作った。

### コード・jdoc
GitHubのURL: https://github.com/TowelMan-public/chat-server
jdocのURL: http://myfree.html.xdomain.jp/jdoc/chat_server/index.html
### APIの説明
APIリストの機能の所に「認証無可」と書かれているやつは「認証JWT」がなくてもアクセスできる。逆にいうと、ほかは「認証JWT」がないと実行できない（=必須）。

#### APIリスト
![API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1597746/186d74c4-a833-c325-63e4-ecffbb60b4bb.png)


#### APIに渡す情報の説明
![APiの引数説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1597746/28359dbb-0890-9db4-c384-cf20bf4d2801.png)


### パッチ処理の内容
パッチ処理では有効でないものをDB上から物理的に削除をする。なお、毎日午前0時に実行するようにしている。
### テスト
各Serviceクラスのメソッド１つにつき、最低でも正常なやつ１つと異常系を１つテストコードを書くようにしている。

### 心がけたこと
出来る限りコードに統一感を持たすこととコードを見やすくすること。

### 反省点
テスト環境はコードを書き始める前に作ればよかった。また、データベースは一回設計したら使い勝手等を考えて、もう一回作るということをすればよかった。（反復）

# クライアント側

## Webアプリ版
Spring bootで作った
### コード・jdoc
GitHubのURL: https://github.com/TowelMan-public/chat-web
jdocのURL: http://myfree.html.xdomain.jp/jdoc/chat_web/index.html
### 大雑把なページ構成
ログインページ、新規ユーザー作成ページ、ユーザー退会確認ページ以外は一つの骨組みの中にタイムリーフのフラグメント機能を使った。骨組みの、サイドメニュー的な部分は途中でajaxで最初に読み込むようにした。また、チャットを送ったりするページでは表示されているより過去のチャットと表示されてるより最新のチャットを表示できるようにした（ajaxにより実現）。
### テスト・デバッグ
テストコードは書かずに、ページを表示させることによりデバッグした。（実際に表示されるページでデバッグしたかったから）
### 心がけたこと
出来る限りコードに統一感を持たすこととコードを見やすくすること。
### 反省点
コントローラクラスの各メソッドの書き方を決めておけばよかった。

## Windowsアプリ
.NET Framework 4.7.2 のWinForms　を使って開発した。

### コード
GitHub: https://github.com/TowelMan-public/chat-winForm

### 心がけたこと
　デザインをとにかくWebアプリ版と同じような感じにするようにした。また、1つのPCで使用者が一人だという前提で作ったため、ユーザー情報をレジストリに保存（パスワードは暗号化されている）し、ログインを自動化できるようにした。これにはこの機能を使わないと認証用トークンが1時間で無効になってしまうため、その都度再ログインしなくてはならなくなるのもある。そのため、内部で、30分ごとに再ログインをし、認証用トークンを更新するようにもしている。それと、トークルームリストなどの情報も5分ごとに更新するようにした。
　また、APIを呼び出す処理の所は時間がかかることを想定し、非同期処理にして、画面の処理を止めないようにしている。その際、バックグラウンドで実行している間はスピナーを表示させるようにした。

### 反省点
　今回は作り方が悪かったのか自作コントロールの関係が複雑になったりしてしまった。そのため、次回からは１つのフォームの中にどんなコントロールが必要でそのコントロールはさらにどんなコントロールが必要なのかをしっかり考えるようにしたい。
　また、Apiを、アプリ起動後初めて叩いたり、叩いてからしばらくしてまた叩くとなぜか異様に時間がかかるのでネットで調べてプロキシ周りが原因なのかと推測してその設定をするコードを書いてみたもののその症状は改善されなかった。なので、次回は、もっとその原因が解決されるようにアプローチするか、その部分だけ違うライブラリを使うようにしたい。

### 修正
2021/7/6
・バリデーションチェックのデザインを修正した
・一部画面遷移の修正

## Androidアプリ
「Android Studio」上で、Apiレベルが21～30で動くように開発した。

### コード
GitHub: https://github.com/TowelMan-public/chat-android

### 心がけたこと
 心がけたところはWin版と同じ。ただ、Win版の時と違い、通知機能を導入してみた。（とはいっても未読のトークの件数を通知するだけ）認証用トークンは、AccountManagerをラッピングしたクラスで静的に、最後に更新した日時を保存させといて、そこから一定時間以上更新されていない状態で求められた時に更新するようにした。それと、例外ハンドラーを自作し、扱いやすくしてみた。

### 反省点・苦労したこと
　ものによってAndroidのAPIレベルが対応していないところがあったりして、そこで少し苦労した。また、Activityなどのライフサイクルをあまり理解していなかったため、状態保持をする意味が最初はわからなかった。
　それと、話がずれるがkotlinは慣れないとちょっと大変でもあるが基本楽しいなと思った

# ビルドとデプロイ
時間がかかってしまったが何とかデプロイできた。ものすごく時間がかかったが、その分新しいものが学べた（と思っている）。

<追記>
日本語の文字化けの問題を解消した。また、全体をhttps化した。
##環境
レンタルサーバ: さくらのVPS
OS: Cent OS 7
DB: MySQL 5.7
JDK: Open JDK 15.0.1
SSL証明書: Let's Encrypt