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
83
84
85
86
87
88
89
90
91
92
using log4net;
using Microsoft.AspNet.SignalR.Hubs;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using VueWebCoreApi.Models;
using VueWebCoreApi.Tools;
 
namespace VueWebCoreApi.SignalR
{
    public class ChatHub : Hub<IChatClient>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private ILog log = LogManager.GetLogger(Startup.repository.Name, typeof(ChatHub));
        ILogger<ChatHub> _logger;
 
        public ChatHub(ILogger<ChatHub> logger, IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _httpContextAccessor = httpContextAccessor;
        }
 
        /// <summary>
        /// 客户端连接服务端
        /// </summary>
        /// <returns></returns>
        public override Task OnConnectedAsync()
        {
            log.Info("开启连接服务");
            var id = Context.ConnectionId;
            _logger.LogInformation($"Client ConnectionId=> [[{id}]] Already Connection Server!");
            return base.OnConnectedAsync();
        }
 
        /// <summary>
        /// 客户端断开连接
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public override Task OnDisconnectedAsync(Exception exception)
        {
            var id = Context.ConnectionId;
            // 使用线程安全方法移除连接
            UserIdsStore.RemoveUser(id);
            _logger.LogInformation($"Client ConnectionId=> [[{id}]] Already Close Connection Server!");
            return base.OnDisconnectedAsync(exception);
        }
 
        /// <summary>
        /// 给所有客户端发送消息
        /// </summary>
        /// <returns></returns>
        public async Task SendMessage(string data)
        {
            await Clients.All.SendAll(data);
        }
 
        /// <summary>
        /// 添加到在线用户列表(线程安全版)
        /// </summary>
        /// <param name="usercode">用户编码</param>
        /// <returns></returns>
        public async Task AddUser(string usercode)
        {
            if (string.IsNullOrEmpty(usercode))
            {
                _logger.LogWarning("AddUser方法接收的usercode为空,忽略操作");
                return;
            }
 
            string cid = Context.ConnectionId;
            try
            {
                // 调用线程安全的添加/更新方法
                UserIdsStore.AddOrUpdateUser(cid, usercode);
                _logger.LogInformation($"用户[{usercode}]的连接[{cid}]已注册到在线列表");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加用户[{usercode}]连接[{cid}]失败");
                throw; // 抛出异常让客户端感知错误
            }
            await Task.CompletedTask; // 无异步操作时返回已完成任务
        }
    }
}