Mac環境でC#を使ってWebサーバを作ったのでメモ。
ちなみにC#はほぼ初心者です。
セットアップ
Mac環境だとhomebrewを使ってmonoをインストールすることで実行・コンパイル環境を得ることができます。
brew install mono
brew link mono # dllファイル、binファイルなどをパスの通った場所にリンクする
コンパイル
コンパイルはmcs
コマンドを使って行います。
C#や.NETのバージョンによっては他のコマンドを使うか-sdk
オプションをつける必要があるようです。
参考:http://noriok.hatenadiary.jp/entry/2014/05/18/163019
dllを指定する場合は-rオプションをつけてやる必要があります。
僕の場合は(下記コードには出てきませんが)Sqliteを使ったので、オプションで指定してやる必要がありました。
mcs -r:Mono.Data.Sqlite.dll *.cs
実行
実行にはmono
コマンドにexeファイルを渡してやります。
mono application.exe
サンプルコード
using System;
namespace WebServer
{
public class Application
{
static void Main (string[] args)
{
Server server = new Server();
server.Start();
}
}
}
using System;
using System.Net;
using System.Text;
using System.Threading;
namespace WebServer
{
public class Server
{
private bool debug = false;
public Server()
{
}
public void Start()
{
HttpListener listener = GetHttpListener();
try
{
listener.Start();
}
catch (Exception e)
{
// Error handling is here
}
StartListenLoop(listener);
}
HttpListener GetHttpListener()
{
var listener = new HttpListener();
listener.Prefixes.Add("http://*:8081");
return listener;
}
void StartListenLoop(HttpListener listener)
{
while (true)
{
HttpListenerContext context = listener.GetContext();
ThreadPool.QueueUserWorkItem(o => HandleRequest(context));
}
}
void HandleRequest(HttpListenerContext context)
{
AddResponseHeader(context);
AddResponseOutput(context);
context.Response.Close();
}
void AddResponseHeader(HttpListenerContext context)
{
context.Response.StatusCode = 200;
}
void AddResponseOutput(HttpListenerContext context)
{
byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes("test");
context.Response.OutputStream.Write(bytes, 0, bytes.Length);
}
}
}
動作確認
mono application.exe # サーバの起動
# 別シェルで
curl http://localhost:8081 # testと返ってくればOK
まとめ
HttpListenerクラスとThreadを使えば簡単にマルチスレッドのWebサーバを組めますね。C#すごい。
ちなみにシングルスレッドだと、curlをfor文使って1000件ぐらい連打したら結構な割合でconnection refusedが返ってきたのでマルチスレッドにしました。
C#の練習ということでSqlite使ってみたり、Loggerクラス作ったりもしたのですが特につまる所もなかったです。
C#でSqliteについてはあまり参考になる文章がなかった(特にLinqは全然見当たらなかった)のでまた記事書くかも。