server
C#
C#Day 15

C#でWebServerを0から作ってみる話 編集

初めに

こちらはC# Advent Calender2017の15日目の記事になります。

まずは リポジトリ

https://github.com/wotakuro/Kotori

これは何?

スマートフォンゲーム向けのAPIサーバーをC#で作れないかなぁと思い、作成中のものです。
ゲーム向けAPIサーバーなので、HTTP経由でJsonでデータを受け取り、Jsonで返す形を想定しています。

個人的な野望のために作っていたんですが、最近は放置プレイモードになってしまってます…。
(今回Qiitaのカレンダーに投稿して思い出そうキャンペーン中です。)

0から作ってみる?

特に何らかのフレームワークを殆どつかわず、Main関数から書いている+下記部分を自作してるので、「0から」と言い張っています。
- HttpServerクラスなどを一切使わず、TCP/IPのSocketを読み書きして実装じゃ
- Jsonも自前で実装じゃ
- O/R マッパー?そんなものReflection使って自前で SQLからC#のObjectを引っ張るのじゃ!

とりあえず0ベースで作ってみての感想。

「車輪の再開発なんて無駄なことは辞めるべき」という意見もあるかと思いますが、勉強には非常になるので、一度は無駄な車輪の再開発をするべきじゃないかなぁと思いました。

今回、Httpのサーバーを自前で書くと決めたことで、色々調べました。知らなかったHttpコードがあったりといろいろな発見があって楽しかったです。

あとは自分で書き起こしているので、色々と好きなような仕組み入れたい放題で楽しいですね!
例えば、Httpサーバーとして立ち上がる前に何らかのデータを読んで置いてから起動するみたいな事も仕込み放題です。

あとは雑に作ってるものの紹介をします。

基本的な構造

大きく三つに分けた形で構成をしています。
- kotori.exe:メインループのプログラムです。Application.dllを動的に読み込み処理します。
- Application.dll:ユーザーが作成するアプリ本体です。
- KotoriCore.dll:Httpの機能本体です。kotori.exe・Application.dllから参照されます

この辺りは、Javaのtomcatのwarファイルを配置したら実行するような構造を真似しようと思ってこうなりました。

簡単なコード例

下記はHttpで受けるAPIを簡単に書いてみたサンプルです

LoginModule.cs
/// <summary>
///  http://localhost:8080/login
/// というアドレスにアクセスが来たらこのモジュールが実行されます
/// </summary>
[WebModule("/login")]
class LoginModule : Kotori.Module.IWebModule
{
    /// <summary>
    /// 実行処理を行います
    /// </summary>
    /// <param name="request">クライアントから来たデータをここから取得してください</param>
    /// <param name="response">クライアントへの応答をこちらへ書き込んでください</param>
    public virtual void Exec( Kotori.Http.HttpRequest request , Kotori.Http.HttpResponse response)
    {
        string str = "login user_id:" + request.getParam["user_id"];
        response.Write(System.Text.Encoding.UTF8.GetBytes(str));
    }
}

IWebModuleを継承したクラスを自動的に列挙し、そこについている[WebModule]Attributeに指定された名前でURLを決定するようになっています。

そして、各モジュールごとに 下記Exec関数をオーバーライドして挙動を書いていく形になっています
virtual void Exec( Kotori.Http.HttpRequest request , Kotori.Http.HttpResponse response)

「responseにHttp経由で渡されたパラメーターが入るので、それを元に処理し、responseに書いていく」
という流れになっています。

このModuleで、ログイン・ガチャを引いた・ゲーム開始等々を用意していくことでゲームのサーバーを作ってしまおうという魂胆です。

現在の課題とか…

そもそも色々作成中で未整備…

す、すみません。。。

"multipart/form-data"未対応…

べ、勉強して実装します。。。

Https対応はどうするつもりなの?

nginxでリバースプロキシすれば…ry

Http 2.0というのがあってですね・・・

まあ後から考えます…。Http 2.0はリソース先読みのプロトコルなど、Webページ向けに有利な設計で、単なるAPIサーバーだと、そこまで大きな利益もないはず…。( Http Headerのパースコストが下がるくらいでは?)
必要になったら勉強します。。。

名前どうしよう・・・・。

「南ことり」さんから、Kotoriっていう名前を付けたんですが…。
うーん。Kotlinと若干被るしなー。などとどうでもよい事に思案していますw

雑多な感じでしたが、以上です。