0

最近、SignalR をよく使っていますが、サーバーとクライアントの通信には本当に素晴らしいと思います。

次に、現在取り組んでいるプロジェクトに非常に関連するシナリオを考えました。

基本的な考え方は、マシンに ping を実行して、サーバーが現在オンラインであるかどうかを Web ページに示すことです。

このプロセスは、最初にページにアクセスしたユーザーによって開始され、すべてのクライアントが切断されたときに停止する必要があります。

これまでの私のサーバーコードは次のとおりです。

public class PingHub : Hub
{
    private static readonly ConcurrentDictionary<string, DateTime> _users = new ConcurrentDictionary<string, DateTime>();
    private static bool _isPolling = false;

    public override Task OnConnected()
    {
        _users.TryAdd(Context.ConnectionId, DateTime.Now);

        return Clients.All.UserCountChanged(_users.Count);
    }

    public override Task OnReconnected()
    {
        _users.AddOrUpdate(Context.ConnectionId, DateTime.Now, (key, value) => value);

        return Clients.All.UserCountChanged(_users.Count);
    }

    public override Task OnDisconnected()
    {
        DateTime value;
        _users.TryRemove(Context.ConnectionId, out value);

        return Clients.All.UserCountChanged(_users.Count);
    }

    public void GetStatus()
    {
        if (_isPolling)
            return;

        _isPolling = true;

        var ping = new Ping();
        do
        {
            var reply = ping.Send("X.X.X.X");

            if (reply == null)
            {
                Clients.Caller.SetError(new { error = "No reply!" });
                break;
            }

            Clients.All.SetStatus(new { Status = reply.Status.ToString(), Time = reply.RoundtripTime });

            Thread.Sleep(500);
        } while (_users.Count > 0);

        _isPolling = false;
    }
}

問題は、ブラウザが閉じられていても、プロセスを開始したユーザーが接続を維持することです (各 ping 要求をログに記録することでこれをテストしました)。

では、意図したとおりにこの作業を行うのを手伝ってくれる人はいますか?

4

1 に答える 1