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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
| using Microsoft.AspNetCore.SignalR;
namespace WebApiDemo.Hubs;
public class ChatHub : Hub
{
// 使用 Dictionary 追踪用戶所在的房間
private static readonly Dictionary<string, string> UserRooms = new();
private static readonly string[] SensitiveWords = new[] { "討厭", "笨蛋", "白痴" };
// 前置需求:記得在 Program.cs 中設定 SignalR 服務
// builder.Services.AddSignalR();
// app.MapHub<ChatHub>("/chatHub");
// 加入房間的方法
public async Task JoinRoom(string user, string roomName)
{
// 檢查用戶是否已在其他房間
if (UserRooms.TryGetValue(Context.ConnectionId, out string? oldRoom))
{
// 從舊房間移除
await Groups.RemoveFromGroupAsync(Context.ConnectionId, oldRoom);
// 通知舊房間的其他用戶
await Clients.Group(oldRoom).SendAsync("ReceiveSystemMessage",
$"用戶 {user} 離開了房間");
}
// 將用戶加入新房間
await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
// 更新用戶房間記錄
UserRooms[Context.ConnectionId] = roomName;
// 通知新房間的所有用戶
await Clients.Group(roomName).SendAsync("ReceiveSystemMessage",
$"用戶 {user} 加入了房間");
}
public async Task SendMessage(string user, string message)
{
if (ContainsSensitiveWords(message, out string foundWord))
{
await Clients.Caller.SendAsync("ReceiveSystemMessage",
$"消息包含敏感詞「{foundWord}」,已被攔截");
return;
}
// 檢查用戶所在的房間
if (UserRooms.TryGetValue(Context.ConnectionId, out string? room))
{
// 只向同一房間的用戶發送消息
await Clients.Group(room).SendAsync("ReceiveMessage", user, message);
}
}
private bool ContainsSensitiveWords(string message, out string foundWord)
{
foundWord = SensitiveWords.FirstOrDefault(word =>
message.Contains(word, StringComparison.OrdinalIgnoreCase));
return foundWord != null;
}
// 當新客戶端連接時觸發
public override async Task OnConnectedAsync()
{
// Context.ConnectionId: 每個連接的唯一標識
await Clients.All.SendAsync("UserConnected", Context.ConnectionId);
await base.OnConnectedAsync();
}
// 當客戶端斷開連接時觸發
public override async Task OnDisconnectedAsync(Exception? exception)
{
// 用戶斷開連接時清理房間資訊
if (UserRooms.TryGetValue(Context.ConnectionId, out string? room))
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, room);
UserRooms.Remove(Context.ConnectionId);
}
await Clients.All.SendAsync("UserDisconnected", Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
}
|