C#でm5stackとhttp通信してみる

[pre-1]:https://qiita.com/zasshyu6/items/c8e218d5a4a26e4eff26

[windoc-1]:https://docs.microsoft.com/ja-jp/dotnet/core/tutorials/with-visual-studio-code
[windoc-2]:https://docs.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclient?view=netframework-4.8
[windoc-3]:https://docs.microsoft.com/ja-jp/dotnet/api/system.net.http.httpresponsemessage?view=netframework-4.8

#はじめに
前回記事、[http通信を勉強する][pre-1]で実際に勉強した上で`http`クライアントのプログラムを作成していきます。

##開発環境

 - windows 10 Home 64bit
 - Visual Studio Code 1.41.1
 - `.NET Core 3.0`


#`C#`で`http`通信するプログラムを作る段取り

 - `VScode`で`C#`の開発環境をセットアップする
 - `C#`で`http`通信プログラムを作成する。


###`VScode`で`C#`の開発環境を構築する
こちらの方はたくさんの方々が記事を挙げているのですごいざっくり紹介です。
せっかくなので`.NET Core`を使っていきます。以下のドキュメントで開始手順が書いているので進めていきましょう。

>[C# および Visual Studio Code の使用を開始する][windoc-1]
microsoft公式なので安心です。


###`C#`で`http`通信プログラムを作成する。
今回はGUIが面倒だったのでコンソールプログラムで作成します。
作るのは`http`のクライアント側なので以下の公式ドキュメントのサンプルを実行してみましょう。
>[HttpClient クラス][windoc-2]
microsoft公式です。
このサンプルでクライアントが送る情報は、`GET`とHost情報(ドメイン名 or IPアドレス)だけでした。

こちらのサンプルはクライアントから非同期スレッド(`GetAsync`が非同期スレッドの様子)で`HttpResponseMessage`を受け取って表示するといったサンプルプログラムになっていますので、`HttpResponseMessage`クラスについてもしらべてみました。

>[HttpResponseMessage クラス][windoc-3]
レスポンスメッセージが詰まっている様子。
コンテンツはstring型のプロパティでゲットできます。
ヘッダー部分は各種特定の型として取得できる様子です。結構な種類があるので全部読むのは時間がかかりそうです。


#実際に`m5stack`とつないでみたよ

<details><summary>C#のコード(アクセスするアドレスを変更しただけ)</summary><div>

```c#:sample

using System;
using System.Threading.Tasks;
using System.Net.Http;

namespace httptest_C_
{
    class Program
    {
        // HttpClient is intended to be instantiated once per application, rather than per-use. See Remarks.
        static readonly HttpClient client = new HttpClient();
        static async Task Main()
        {
            // Call asynchronous network methods in a try/catch block to handle exceptions.
            try
            {
                HttpResponseMessage response = await client.GetAsync("http://192.168.10.254/");
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                // Above three lines can be replaced with new helper method below
                // string responseBody = await client.GetStringAsync(uri);
                Console.WriteLine(responseBody);
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine("\nException Caught!");
                Console.WriteLine("Message :{0} ", e.Message);
            }
        }
    }
}

````

</details></div>

結果は以下になりました。
最初はリクエストメッセージ(`C#` -> `m5stack`)

```
GET / HTTP/1.1

Host: 192.168.10.254
```

次はレスポンスメッセージ(`C#` <- `m5stack`)

```
Click <a href="/H">here</a> to turn ON the LED.<br>Click <a href="/L">here</a> to turn OFF the LED.<br>
```

うーん、ほんとにシンプルで男らしい・・・
`m5stack`側は上記の`html`とステータスコード(`HTTP/1.1 200 OK`),コンテンツタイプ(`Content-type:text/html`)が来ているはずですが、表示するように作っていないので表示されていません

###今回引っかかったこと

 - `C#`のビルドがない!?
    - [この公式チュートリアル][windoc-1]だといきなりコンソールプログラムを作成して`run`コマンドで実行してデバッグの説明に入っていますが、`build`に関してはコマンド名が出てくるのみとなっていたのでてっきり`run`を実行するとビルドされるものだと勘違いしました。
    - `build`に関して、VisualStudio2017などではコンパイルするとファイルの保存をコンパイルが同時に実行されますが、VScodeでは保存しないと前のファイルをコンパイルしてしまいます。パワーシェル？コマンドプロンプト？でビルドを行うので当たり前なのですが慣れないと絶対忘れますね・・・
 - `.NET Core`には`httpclient`がない！？
    - 初めに、サンプルを実行しようとしたのですが、usingディレクティブが見つかりませんと出てきました。なんでだろう？と色々試した結果、`system.NET.Http`の`H`を大文字にしていなかったのが原因でした。コードインテリジェンスを使用して`tab`で楽していたのがはまった原因でした。

#まとめ
今回は`C#`で`.NET Core`を使った`http`通信を`m5stack`とやってみました。使うだけなら非常に楽なのですが、実際に作りこむとなると`HttpResponseMessage`のヘッダー部分やステータスコードを判別対象に使わないといけないのでまた勉強が必要そうです。
また、`VSCode`で今回は作りましたが、結構コードインテリジェンスが効かない印象を受けました。(`Visual Studio`が効きすぎなだけかもですが・・・)
ですが、自分のような浅い初心者ではコードインテリジェンスがないと型がわからなかったりこの型で合ってるのか確認するのに時間がかかるのでこれはこれでやりにくかったです。
`m5stack`は`VSCode`でやってるのでやれるのならばいっしょにしたいのですが、何かいい手はないでしょうかねぇ・・・

次回は`swift`で`http`通信を行ってみたいと思います。
有意義な年末ライフをぜひお楽しみください！