using Microsoft.AspNetCore.SignalR;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
public class ChatHub : Hub
{
private static readonly ConcurrentDictionary<string, string> ConnectedUsers = new();
public async Task UserConnected(string userName)
{
ConnectedUsers[Context.ConnectionId] = userName;
await Groups.AddToGroupAsync(Context.ConnectionId, "ChatRoom");
Console.WriteLine($"准备广播 UserJoined 事件给其他用户,用户名: {userName}");
await Clients.All.SendAsync("UserJoined", userName);
Console.WriteLine($"已向所有客户端发送 UserJoined 事件");
await Clients.Others.SendAsync("UserJoined", userName + "_Others");
Console.WriteLine($"已向其他客户端发送 UserJoined_Others 事件");
Console.WriteLine($"用户 {userName} 已连接,连接ID: {Context.ConnectionId}");
}
public async Task SendMessage(string user, string message)
{
Console.WriteLine($"收到消息 - 用户: {user}, 内容: {message}");
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task SendMessageToGroup(string groupName, string user, string message)
{
await Clients.Group(groupName).SendAsync("ReceiveMessage", user, message);
}
public async Task JoinGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("UserJoinedGroup", Context.User?.Identity?.Name, groupName);
}
public async Task LeaveGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("UserLeftGroup", Context.User?.Identity?.Name, groupName);
}
public async IAsyncEnumerable<int> StreamData(
int count,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
for (var i = 0; i < count; i++)
{
cancellationToken.ThrowIfCancellationRequested();
yield return i;
await Task.Delay(1000, cancellationToken);
}
}
public async IAsyncEnumerable<string> StreamTimestamps(
int durationInSeconds,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
var endTime = DateTime.Now.AddSeconds(durationInSeconds);
while (DateTime.Now < endTime)
{
cancellationToken.ThrowIfCancellationRequested();
yield return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
await Task.Delay(500, cancellationToken);
}
}
public async IAsyncEnumerable<StreamDataModel> StreamComplexData(
int count,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
var random = new Random();
for (var i = 0; i < count; i++)
{
cancellationToken.ThrowIfCancellationRequested();
yield return new StreamDataModel
{
Id = i,
Message = $"Stream message {i}",
Timestamp = DateTime.Now,
Value = random.NextDouble() * 100
};
await Task.Delay(800, cancellationToken);
}
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
if (ConnectedUsers.TryRemove(Context.ConnectionId, out string? userName))
{
await Clients.Others.SendAsync("UserLeft", userName);
Console.WriteLine($"已向其他客户端发送 UserLeft 事件,用户名: {userName}");
}
Console.WriteLine($"用户断开连接,连接ID: {Context.ConnectionId}");
if (exception != null)
{
Console.WriteLine($"断开连接异常: {exception.Message}");
}
await base.OnDisconnectedAsync(exception);
}
}