C#でSignalRを使用した通信を行いたい その9(一部クライアントメソッドしか実行しない) | プログラミングがわからなすぎる

プログラミングがわからなすぎる

気が向いた時の備忘録。プログラミングは好きなのに物凄く単純なものしか理解できないからメモしていくうちに覚えられたらいいな
ターゲットフレームワークは大体4.7.2

前回は一部クライアントを仲間外れにして

サーバからクライアントに通知を送信してみましたが

今回は逆に一部クライアントにしか通知を送信しないようにしてみます

 

仲間外れにしたいクライアントが多い時に使えます

 

クライアント側のプロジェクト 

画面・プログラムは前回と変わりません

 

サーバ側のプロジェクト 

 

 TestHub.cs

using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace SignalRServerTest
{
    public class TestHub : Hub
    {
        public void AnnounceSendName()
        {
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                "名前が送信されました");
        }

        public void GetName(string name)
        {
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                "名前:" + name);
            FormSet.clients.Add(Context.ConnectionId, name);
        }

        public List<string> SendOurNames()
        {
            List<string> names = new List<string>(FormSet.clients.Values);
            return names;
        }

        public bool ExitChatRoom(string name)
        {
            if (FormSet.clients[Context.ConnectionId] == name)
            {
                FormSet.clients.Remove(Context.ConnectionId);
                FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                    name + "さんが退出しました。");
                return true;
            }
            else
            {
                FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                    name + "さんの退出処理に失敗しました。");
                return false;
            }
        }

        public void CatchMessage(string msg)
        {
            string name = FormSet.clients[Context.ConnectionId];
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                name + "が発言しました。");
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), msg);
            Clients.All.CatchTalk(name + ":" + msg);
        }

        public void CatchMessageEx(string msg, string exName)
        {
            string name = FormSet.clients[Context.ConnectionId];
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                name + "が発言しました。");
            string exConID = "";
            foreach (string con in FormSet.clients.Keys)
            {
                if (exName == FormSet.clients[con])
                {
                    exConID = con;
                    break;
                }
            }
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), 
                exName + "を除外して送信します。");
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), msg);
            Clients.AllExcept(exConID).CatchTalk(name + ":" + msg);
            Clients.Client(exConID).CatchTalk("内緒話中です。");
        }

        public override Task OnConnected()
        {
            object a = FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), Context.ConnectionId + "が接続しました");
            return base.OnConnected();
        }
        public override Task OnDisconnected(bool stopCalled)
        {
            FormSet.form.Invoke(new Action<string>(FormSet.form.ShowMessage), Context.ConnectionId + "が切断しました");
            return base.OnDisconnected(stopCalled);
        }
    }
}

前回Hubクラスに追加したCatchMessageExメソッドで

Clients.Clientに除外対象の接続IDを設定してみます

 

会話から除外されている人のメッセージ表示枠に

「内緒話中です。」と表示されたら成功です

 

動かしてみる 

サーバ画面(後ろに隠れてます)を起動して

クライアント3窓を接続・名前の設定までしてしまいます

 

左のウィンドウから除外の設定をせずに発言してみると、ちゃんと全員に届いています

 

右のウィンドウで、にんげんを除外して発言してみます

 

にんげんのウィンドウに内緒話されていることが報告されています

 

真ん中のウィンドウでにんげんを除外してもう一度発言してみます

 

またにんげんのウィンドウに内緒話がばれています

 

一部クライアントのメソッドしかサーバから実行させないメモ 

 

Clients.Client(接続ID).メソッド名(引数);

上記は1つのクライアントに対して通知を送信できるみたいなので

複数クライアントに対して通知を送信したい場合は

 Clients.Clients(接続IDリスト).メソッド名(引数);

でいけるみたいです

※接続IDリスト:List<string>型の接続ID