[鐵人賽Day7] SignalR 群組概念與使用

今天來介紹群組的運作,不知道會不會有人問為什麼要群組??總不能每次訊息都傳給所有人吧!XD

所以今天就讓我們好好來介紹一下SignalR群組運作的方式。

使用方法

主要就使用3個方法,Groups.AddToGroupAsync()RemoveFromGroupAsync()Clients.Group()3種。

加入群組使用

1
Groups.AddToGroupAsync(Context.ConnectionId, groupName);

退出群組使用

1
Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
  • Context.ConnectionId為前端SignalR產生的ID
  • groupName為要加入的群組

群組傳送訊息使用Clients.Group()

1
Clients.Group(groupName).SendAsync("SendGroupMethod", "GroupMessage");

groupName是要傳送得群組 SendAsync()第一個參數為回傳要呼叫的前端方法,可任意修改名稱,第二個參數為回傳的訊息。

大概就這樣,感覺好像沒講什麼….. 那帶大家來實做一下吧!!

群組實作

我們用Day3得實作為基礎繼續做下去,如果沒做到的可以往回看Day3。

後端部分

首先我們在Hub新增方法AddGroup(),用來加入群組使用,內容大概像下面這樣

1
2
3
4
5
public async Task AddGroup(string groupName, string username)
{
    await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
    await Clients.Group(groupName).SendAsync("RecAddGroupMsg", $"{username} 已加入 群組:{groupName}。");
}

AddToGroupAsync()加入群組後,再回傳一個群組訊息告知大家誰加入了群組。

在建立一個群組傳送訊息的方法SendMessageToGroup()

1
2
3
4
public Task SendMessageToGroup(string groupName, string username, string message)
{
    return Clients.Group(groupName).SendAsync("ReceiveGroupMessage", groupName, username, message);
}

跟上面的方法大同小異,只是多個訊息變數,還有傳回去時要多傳一個使用者,讓大家知道是誰傳的。

前端部分

首先我們要創建一個群組列表和加入群組按鈕,讓大家選擇要加入哪一個群組,群組就用很多人喜歡的貓派狗派來當示範。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<select id="group">
    <option>貓派</option>
    <option>狗派</option>
</select>
<button type="button" id="addGroupBtn">加入群組</button>
<br>
姓名:<input id="name" type="text"><br>
訊息<input id="msg" type="text">
<br>
<button type="Button" id="submitGroupBtn">送出給群組</button>
<button type="Button" id="submitAllBtn">送出給所有人</button>    
<br>
<div id="msgDiv"></div>

建立加入群組的事件到ButtonClick裡,然後傳回給AddGroup

1
2
3
4
5
6
7
8
document.getElementById("addGroupBtn").addEventListener("click", function (event) {
    var user = document.getElementById("name").value;
    var group = document.getElementById("group").value;
    connection.invoke("AddGroup",group, user ).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

建立接收的事件,用來接收群組是否加入成功

1
2
3
4
5
6
connection.on("RecAddGroupMsg", function (message) {
    var msg = message;
    var li = document.createElement("li");
    li.textContent = msg;
    document.getElementById("msgDiv").appendChild(li);
});

再來建立群組訊息事件和接收事件,顯示的訊息我們可以顯示是群組還是所有人,所以我們連原本的訊息格式也改一下吧!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 群組訊息Button事件
document.getElementById("submitGroupBtn").addEventListener("click", function (e) {
    var user = document.getElementById("name").value;
    var group = document.getElementById("group").value;
    var message = document.getElementById("msg").value;

    connection.invoke("SendMessageToGroup",group, user, message ).catch(function (err) {
        return console.error(err.toString());
    });
});

// 群組訊息接收事件
connection.on("ReceiveGroupMessage", function (groupName, user, message) {
    var msg = `[群組訊息(${groupName})]${user}${msg}`;
    var li = document.createElement("li");
    li.textContent = msg;
    document.getElementById("msgDiv").appendChild(li);
});

// 全頻道訊息訊息事件
connection.on("ReceiveMessage", function (user, message) {
    var msg = `[全頻道訊息(${groupName})]${user}${msg}`;
    var li = document.createElement("li");
    li.textContent = msg;
    document.getElementById("msgDiv").appendChild(li);
});

這樣就大功告成了!

DEMO

參考 & 範例下載

comments powered by Disqus
使用 Hugo 建立
主題 StackJimmy 設計