(クライアント側)JavaScriptコード:
// サーバーイベントストリームの接続処理
$(function () {
if (typeof (EventSource) !== "undefined") {
// メッセージ表示領域の指定
const outputArea = document.getElementById("EventOutput");
// イベントストリームの初期化
const stream = new EventSource("/api/EventStream/InitConnection");
// 接続確立時の処理
stream.onopen = function (e) {
outputArea.innerHTML += "接続成功<br/>";
}
// メッセージ受信時の処理
stream.onmessage = function (e) {
outputArea.innerHTML += e.data + "<br/>";
};
// エラー発生時の処理
stream.onerror = function (e) {
outputArea.innerHTML += "接続エラー<br/>";
stream.close();
}
}
else {
console.log("ブラウザがイベントストリームに対応していません!");
}
})
(サーバー側)C# MVCコントローラコード:
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
namespace CabinetMS.Controllers.Api
{
/// <summary>
/// イベントストリームメッセージの定義
/// </summary>
public class ServerMessageData
{
public string MessageId { get; set; }
public string Content { get; set; }
}
/// <summary>
/// イベントストリーム接続処理
/// </summary>
[RoutePrefix("api/EventStream")]
public class EventStreamController : ApiController
{
// クライアント接続処理
[HttpGet, Route("InitConnection")]
public HttpResponseMessage InitConnection(HttpRequestMessage request)
{
var response = request.CreateResponse();
response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)InitializeStream, new MediaTypeHeaderValue("text/event-stream"));
return response;
}
private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> activeStreams = new ConcurrentDictionary<StreamWriter, StreamWriter>();
public void InitializeStream(Stream output, HttpContent content, TransportContext context)
{
var writer = new StreamWriter(output);
activeStreams.TryAdd(writer, writer);
}
// クライアントへのメッセージ送信メソッド
public static void SendClientMessage(ServerMessageData message)
{
BroadcastMessage(message);
}
// メッセージ送信処理
private static void BroadcastMessage(ServerMessageData message)
{
foreach (var connection in activeStreams.ToArray())
{
try
{
connection.Value.WriteLine($"id: {message.MessageId}\n");
connection.Value.WriteLine($"data: {message.Content}\n\n");
connection.Value.Flush();
}
catch
{
StreamWriter disconnected;
activeStreams.TryRemove(connection.Value, out disconnected);
}
}
}
}
}
(サーバー側)ストリーム確立後のメッセージ送信例:
// クライアントへ通知送信
var notification = new ServerMessageData();
notification.MessageId = "ALERT-001";
notification.Content = "システム通知メッセージ";
EventStreamController.SendClientMessage(notification);