アドベントカレンダー9日目の記事になります!(現在12/10だけど大丈夫!あとでデータベース改ざんして12/9に投稿したことにする!) さて、Blazor WebAssenblyですね。開発環境の導入記事は こちら 前回はプロジェクトの生成とforeach文で<p>要素を記載するところまでやりましたね。
今回作るチャットアプリ
チャットアプリに関しては、こちらのリポジトリのものを作成していきます。 MogamiTsuchikawa/CSharpChat リポジトリ内に今回作るチャットアプリのサーバー側コードもありますので動作検証用にクローンしておくことをおすすめします。
概要
名前と部屋名を記入して接続ボタンを押したら接続されて同じ部屋名の人とメッセージを送り合えるシステムを作ります。 内部的にはWebSocketを使って接続を行います。 通常クライアント側から能動的にアクセスしないと通信できないHTTP通信と違い、WebSocketでは一度接続してしまえば接続解除するまでサーバーからクライアントへデータ送信が可能です。なので、コンテンツ更新の通知や今回のようなチャットアプリの実装に向いています。 WebSocketの実装ですが、今回のクライアントサイドはMicrosoftが標準で提供しているAPIのみで実装を行うので、通信を担うクラスはデスクトップアプリやXamarinでのスマホアプリなどでもコードを共有することが可能かと思います。そういうビジネスロジック周りを共有できるのもBlazor WebAssenblyの利点と言えますね。
フロントエンドの実装
まず、画面構成を考えます。 チャットルームログイン前はチャット内で使う名前と接続先のチャット部屋名を入力する部分、これと「接続」ボタンを配置する必要があります。
プロジェクト作成
前回のプロジェクト作成を参考にしながら、「WebChatApp」というプロジェクトを生成します。
Chatページの作成
プロジェクトフォルダ内のPages
フォルダ内にChat.razor
ファイルを作成し、内容を次のようにします。
(VisualStudioではPagesを右クリックして追加からRazorコンポーネント
を選択します)
@page "/chat"
<PageTitle>チャットページ</PageTitle>
<h1>シーシャープdeチャットッ★</h1>
@code{
}
これが基本形です。
@page "/chat"
はページへのルーティングを表しています。
<PageTitle>
はページのタイトル要素(ブラウザのタブに表示されるテキストです。
@code{}
内は前回の内容から分かるとおり、C#でプログラムを記述するところになります。
テキスト入力とボタン
まずはボタンを配置してみましょう そしてボタンが押された際に接続済と表示されるようにします。
@page "/chat"
<PageTitle>チャットページ</PageTitle>
<h1>シーシャープdeチャットッ★</h1>
@if (isConected)
{
<h3>接続済</h3>
}
<button @onclick="OnClickConnectBtn">接続</button>
@code{
private bool isConected = false;
private void OnClickConnectBtn()
{
isConected = true;
}
}
前回同様実行し、/chat
ページへアクセスすると図のようになります。
良い感じですね。 そのままユーザー名や部屋名を入力するinput要素を用意していきます。
@page "/chat"
<PageTitle>チャットページ</PageTitle>
<h1>シーシャープdeチャットッ★</h1>
@if (isConected)
{
<h3>接続済:@inputRoomName</h3>
}
<p>ユーザー名</p>
<input type="text" @bind-value="inputUserName" @bind-value:event="oninput"/>
<p>部屋名</p>
<input type="text" @bind-value="inputRoomName" @bind-value:event="oninput"/>
<button @onclick="OnClickConnectBtn">接続</button>
@code{
private bool isConected = false;
private string inputUserName = "", inputRoomName = "";
private void OnClickConnectBtn()
{
isConected = true;
}
}
input要素に対しては@bind-value
で@code
内のstring
型の変数と紐付けます。また、@bind-value:event="oninput"
で入力時に順次変数に代入が行われます。ここら辺React
と比べると少し便利ですね。
追加でisConnected
がtrueになったさいに、接続済:(部屋名)になるように@inputRoomName
を入れました。
とりあえず、ここまである程度動作確認が取れましたね。 次にプログラム全体を接続前はユーザー名や部屋名入力を出して、接続後はチャットの入力欄を表示するようにします。 更にチャットのメッセージ投稿メソッドも作成します(中身はまだ作りません) 今までやった事の活用なのでコード自体は解説は行いません。
@page "/chat"
<PageTitle>チャットページ</PageTitle>
<h1>シーシャープdeチャットッ★</h1>
@if (isConected)
{
<h3>接続済:@inputRoomName</h3>
<br />
<input type="text" @bind-value="inputMsgText" @bind-value:event="oninput" />
<button @onclick="OnClickPostMsgBtn">投稿</button>
}
else
{
<p>ユーザー名</p>
<input type="text" @bind-value="inputUserName" @bind-value:event="oninput"/>
<p>部屋名</p>
<input type="text" @bind-value="inputRoomName" @bind-value:event="oninput"/>
<button @onclick="OnClickConnectBtn">接続</button>
}
@code{
private bool isConected = false;
private string inputUserName = "", inputRoomName = "", inputMsgText = "";
private void OnClickConnectBtn()
{
isConected = true;
}
private void OnClickPostMsgBtn()
{
inputMsgText = "";
}
}
とりあえず今回はここまで 次回はWebSocketやJson周りなどロジックの実装を中心に行います。