C#だけでHTTPサーバーをGUIアプリ(WinForms)に組み込む方法

コンピュータ

C#から比較的簡単にhttpサーバーを作ることが出来るとのことですので、WinFormで作るGUIアプリにhttpサーバーを組み込むサンプルを試しました。

プロジェクトの作成

mkdir WinFormsHttpServerSample
cd WinFormsHttpServerSample
dotnet new winforms -f net8.0

ソースコード

using System.Net;
using System.Text;

namespace WinFormsHttpServerSample;

public partial class Form1 : Form
{
    private readonly string _serverAddress = "http://localhost:8080/";
    private HttpListener? _listener;
    private CancellationTokenSource? _cts;
    public Form1()
    {
        InitializeComponent();
        StartHttpServer();
    }
    private void StartHttpServer()
    {
        _cts = new CancellationTokenSource();
        _listener = new HttpListener();
        _listener.Prefixes.Add(_serverAddress);
        try
        {
            _listener.Start();
            Task.Run(() => ListenLoopAsync(_cts.Token));
        }
        catch (HttpListenerException ex)
        {
            MessageBox.Show("HTTPサーバーの起動に失敗しました: " + ex.Message);
        }
    }

    private async Task ListenLoopAsync(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            try
            {
                var context = await _listener!.GetContextAsync();
                var response = context.Response;
                var buffer = Encoding.UTF8.GetBytes("hello WinForms");

                response.ContentLength64 = buffer.Length;
                response.ContentType = "text/plain";
                await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
                response.Close();
            }
            catch (Exception ex) when (ex is not OperationCanceledException)
            {
                Invoke((Action)(() =>
                    MessageBox.Show("サーバーエラー: " + ex.Message)));
            }
        }
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        _cts?.Cancel();
        _listener?.Stop();
    }

}

実行

dotnet run

白紙のウィンドウが表示されますがUIとしての機能は無いです。強いて言えばウィンドウを閉じるだけです。

PowerShellでアクセスしてみる。

Invoke-RestMethod -Uri "http://localhost:8080/"
hello WinForms

感想

コメント