集线器 SignalR.Core 消息推送实例

发布时间 2023-09-10 18:40:36作者: baivfhpwxf

SignalR.Core 消息推送实例

public class ChatHub : Hub
{
    private string _className = "ChatHub";

    //private System.Threading.Timer timer = null;
    private System.Threading.Timer _timer = null;
    private static readonly object _lock = new object();

    /// <summary>
    /// 前端接口接收消息的方法名
    /// </summary>
    private string _receiveMsgmethod = "chatHubReceiveMsg";

    /// <summary>
    /// 前端接口注册用户的方法名
    /// </summary>
    private string _registerUserthod = "chatHubRegisterUsert";

    /// <summary>
    /// 系统消息发送人
    /// </summary>
    private string _sendUser = "system";

    private ITokenHelper _tokenHelper = new TokenHelper();

    /// <summary>
    /// 当连接成功时执行
    /// </summary>
    /// <returns></returns>
    public override Task OnConnectedAsync()
    {
        try
        {
            string connId = Context.ConnectionId;
            var tokenobj = Context.GetHttpContext().Request.Query["token"].ToString();
            var uid = Context.GetHttpContext().Request.Query["uid"].ToString();
            //读取配置文件中 的 秘钥
            var secretKey = ConfigManagerHelper.JwtTokenConfig["Secret"];
            if (!string.IsNullOrEmpty(tokenobj))
            {
                //var userId = string.Empty;                    
                //string token = tokenobj.Split(" ")[1].ToString();//剔除Bearer
                ////string mobile = "";//用户手机号
                ////                   //验证jwt,同时取出来jwt里边的用户ID
                //TokenType tokenType = _tokenHelper.ValiTokenState(token, secretKey
                //    , a => a["iss"] == "test.cn" && a["aud"] == "test"
                //    , action =>
                //    {
                //        userId = action["id"];
                //        //mobile = action["phone_number"];
                //    });
                var userModel = new OnlineUserModel() {
                    Token = tokenobj,
                    F_Id = uid,
                    ConnectionId = connId,
                    HubClients = Clients
                };
                OnlineUserService.Instance.AddOnlineUser(userModel);
                /*根据令牌获取用户的信息*/
                //{
                //    await RedisClient.Instance.SetAsync("缓存key-用户标识", this.Context.ConnectionId);
                //}
            }
            //_logger.LogWarning("SignalR已连接");
            //验证Token
            //var token = _accessor.HttpContext.Request.Query["access_token"];
            //var user = JwtHelper.SerializeJwt(token);
            //ApiLogQueueService.Instance.AddLog(_className, "OnConnectedAsync", ApiLogType.Warning, ProjectIdEnum.LDApi.GetHashCode(), 200, token, "SignalR已连接,用户名:" + CurrentUserName, string.Empty, 200, 0, CommonHelp.ServiceIp);
            //_logger.LogWarning("SignalR已连接,用户名:" + CurrentUserName);
            //连接用户 这里可以存在Redis
            //var model = new T_sys_userModel
            //{
            //    p_attribute1 = connId
            //};
            OnlineUserService.Instance.AddClients(connId, Clients);
            //var msgModel = new MessageModel()
            //{
            //    SendUserID = connId,
            //    SendUserName = secretKey,
            //    Msg = connId + "连接成功,uid:" + uid,
            //    Type = MessageTypeEnum.System.GetHashCode(),
            //    City = tokenobj
            //};
            //Clients.All.SendAsync("chatHubConnectResponse", _sendUser+ "OnConnectedAsync", msgModel);//connId + "连接成功"
            TimerSend();
        }
        catch (Exception ex)
        {
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "OnConnectedAsync",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "OnConnectedAsync",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_SendMessageAsync.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_SendMessageAsync,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        //给当前的连接分组 可以进行同一组接收消息 也可以用Token获取机构权限
        //await Groups.AddToGroupAsync(Context.ConnectionId, "测试组");

        //给当前连接返回消息 .Clients可以发多个连接ID
        //Clients.Client(connId).SendAsync("ConnectResponse",
        //    new AjaxResultModel<T_sys_userModel>()
        //    {
        //        state = 200,
        //        data = model,
        //        message = model.p_attribute1 + "连接成功"
        //    });

        return base.OnConnectedAsync();
    }

    /// <summary>
    /// 当连接断开时的处理
    /// </summary>
    public override Task OnDisconnectedAsync(Exception exception)
    {
        try
        {
            //var token = Context.GetHttpContext().Request.Query["token"].ToString();
            //var uid = Context.GetHttpContext().Request.Query["uid"].ToString();
            //var userModel = OnlineUserService.Instance.GetUserByConnectionId(connId);
            string connId = Context.ConnectionId;                
            OnlineUserService.Instance.RemoveClients(connId);
            //if (Clients != null)
            //{
            //    var msg = connId + "断开连接";
            //    if (userModel != null)
            //    {
            //        msg = userModel.F_RealName + "断开连接";
            //    }
            //    var msgModel = new MessageModel()
            //    {
            //        SendUserID = connId,
            //        SendUserName = string.Empty,
            //        Msg = msg + "uid:" + uid,
            //        Type = MessageTypeEnum.System.GetHashCode(),
            //        City = token
            //    };
            //    Clients.All.SendAsync("chatHubDisconnectResponse", _sendUser, msgModel);
            //}
        }
        catch (Exception ex)
        {
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "OnDisconnectedAsync",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "OnDisconnectedAsync",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_SendMessageAsync.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_SendMessageAsync,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return base.OnDisconnectedAsync(exception);
    }

    /// <summary>
    /// 定时器
    /// </summary>
    /// <returns></returns>
    private void TimerSend()
    {
        //System.Threading.Timer t = new System.Threading.Timer(SendMessageAsync, null, 0, 1000);
        //if (_timer == null)
        //{
        //    lock (_lock)
        //    {
        //        if (_timer == null)
        //        {
        //            _timer = new System.Threading.Timer(SendMessageAsync, null, 0, 60000);
        //        }
        //    }
        //}
    }

    /// <summary>
    /// 发信息 ok
    /// </summary>
    /// <returns></returns>
    private void SendMessageAsync(object a)
    {
        try
        {
            var msg = "[" + CommonHelp.ServiceIp + "]系统消息:现在是" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            //var task = _hubClients.All.SendAsync("Show", "system", msg);
            //var task = hubClients.All.SendAsync(_receiveMsgmethod, "system", msg);
            var task = OnlineUserService.Instance.SendPublicMsg(msg, "systemId", "system");
            //task.Wait();

            //var msg = "系统消息:现在是" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            ////var task =_hubContext.Clients.All.SendAsync("Show", "system", "系统消息:现在是" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            //var task = OnlineUser.Values.All.SendAsync("Show", "system", msg);
            //task.Wait();
            //if (Clients != null)
            //{
            //    //string userid = Guid.NewGuid().ToString();
            //    var msg = "系统消息:现在是" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            //    //var task =_hubContext.Clients.All.SendAsync("Show", "system", "系统消息:现在是" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            //    var task = Clients.All.SendAsync("Show", "system", msg);
            //    task.Wait();
            //    //var isSucceed = _userLoginLogService.Add(new Admin.Models.Tables.TB_UserLoginLogModel()
            //    //{
            //    //    F_Id = Guid.NewGuid().ToString("N"),
            //    //    F_ClientIP = msg,
            //    //    F_LoginTime = DateTime.Now,
            //    //    F_LoginType = "登录",
            //    //    F_ServiceType = "登录",
            //    //    F_UserId = "system",
            //    //});
            //    //var aa = isSucceed;
            //}
        }
        catch (Exception ex)
        {
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "SendMessageAsync",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "SendMessageAsync",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_SendMessageAsync.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_SendMessageAsync,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
    }

    /// <summary>
    /// 开始计时器  前端调用 invoke
    /// </summary>
    private void startReminbScheduleTimer()
    {
        //设置定时间隔(毫秒为单位)
        //int interval = 3000;//60000一分钟
        //timer = new System.Timers.Timer(interval);
        ////设置执行一次(false)还是一直执行(true)
        //timer.AutoReset = true;
        ////设置是否执行System.Timers.Timer.Elapsed事件
        //timer.Enabled = true;
        ////绑定Elapsed事件 需要执行的事件
        //timer.Elapsed += new System.Timers.ElapsedEventHandler(ReminbSchedule);
        //timer.Start();
    }

    /// <summary>
    /// 日程提醒
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    //public async void ReminbSchedule(object sender, ElapsedEventArgs e)
    public void ReminbSchedule(object sender)
    {
        try
        {
            //获取需要此人需要提醒的日程 
            DateTime StartTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:00"));
            DateTime EndTime = StartTime.AddMinutes(1);

            //var taskPublicSendMsg = SendMsg("system", "[" + CommonHelp.ServiceIp + "]系统消息:现在是" + StartTime.ToString("yyyy-MM-dd HH:mm:ss"));
            //taskPublicSendMsg.Wait();
            var task = OnlineUserService.Instance.SendPublicMsg("[" + CommonHelp.ServiceIp + "]系统消息:现在是" + StartTime.ToString("yyyy-MM-dd HH:mm:ss"), "systemId", "system");
            //task.Wait();

            //var list = getRemindSchedule(StartTime, EndTime);
            ////if (Type = 1)//1系统消息 2 电子邮件 3 系统弹窗
            ////{ 

            ////}

            //// var currentuserid = Context.UserIdentifier; 
            ////前端 判断Direct类型 为3时时日程提醒
            //foreach (var item in list)
            //{
            //    //IpAddress:日程ID      Time:(2 天前 · 日历 · 2021年12月28日 16:00 - 2021年12月28日 18:00)
            //    var timestr = LD.Code.Common.DateStringFromNow(item.RemindTime) + "· 日历 ·" + item.F_StartTime.ToString("yyyy年MM月dd日 HH:00") + " - " + item.F_EndTime.ToString("yyyy年MM月dd日 HH:00");
            //    var t = Clients.User(CurrentUserId).SendAsync("ReceiveMessage", new MessageModel() { UserID = CurrentUserId, Name = CurrentUserName, Msg = item.F_Title, Direct = 3, IpAddress = item.F_Id, Time = timestr });
            //    await Task.WhenAll(t);
            //    //标记为已提醒
            //    await UpdateRemind(item.ReminbId, item.IsEdit);
            //}
        }
        catch (Exception ex)
        {
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "ReminbSchedule",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "ReminbSchedule",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_ReminbSchedule.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_ReminbSchedule,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
    }

    /// <summary>
    /// 给连接的所有人发送消息
    /// </summary>
    /// <param name="username"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    //public Task SendMsg(string username, string message)
    //{
    //    //Show方法需要在前端实现
    //    return Clients.All.SendAsync("Show", username, message);
    //}

    /// <summary>
    /// 公共消息
    /// </summary>
    /// <param name="message"></param>
    /// <param name="sendUserId"></param>
    /// <param name="sendUserName"></param>
    /// <returns></returns>
    public async Task PublicSendMsg(string message, string sendUserId, string sendUserName)
    {
        // 后期考虑后台管理添加系统通知,这里来查 通知到链接的人
        //var hubClients = OnlineUserService.Instance.GetClient();
        //if (hubClients != null)
        //{
        //    var t1 = hubClients.All.SendAsync(_receiveMsgmethod, _sendUser, message);//new { Msg = message, Direct = 0 }
        //    var t2 = this.InsertMessage(0, CurrentUserId, userId, message); ;//添加历史记录
        //    await Task.WhenAll(t1);//, t2
        //}
        if (!string.IsNullOrEmpty(message) && !string.IsNullOrEmpty(sendUserId) && !string.IsNullOrEmpty(sendUserName))
        {
            var t1 = OnlineUserService.Instance.SendPublicMsg(message, sendUserId, sendUserName);
            //t1.Wait();
        }
    }

    /// <summary>
    /// 发送组消息
    /// </summary>
    /// <param name="groupId"></param>
    /// <param name="message"></param>
    /// <param name="sendUserId"></param>
    /// <param name="sendUserName"></param>
    /// <returns></returns>
    public async Task SendGroupMsg(string groupId,string message, string sendUserId, string sendUserName)
    {
        // 后期考虑后台管理添加系统通知,这里来查 通知到链接的人
        if (!string.IsNullOrEmpty(message) && !string.IsNullOrEmpty(sendUserId) && !string.IsNullOrEmpty(sendUserName))
        {
            var t1 = OnlineUserService.Instance.SendGroupMsg(groupId, message, sendUserId, sendUserName);
            //t1.Wait();
        }
    }

    /// <summary>
    /// 注册用户消息
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="userName"></param>
    /// <param name="connectionId"></param>
    /// <returns></returns>
    public void RegisterUser(string userId, string userName, string connectionId)
    {
        try
        {
            // 后期考虑后台管理添加系统通知,这里来查 通知到链接的人
            var hubClients = OnlineUserService.Instance.GetClient();
            if (hubClients != null)
            {
                if (!string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(connectionId))
                {
                    OnlineUserService.Instance.AddOnlineUser(new OnlineUserModel()
                    {
                        F_Id = userId,
                        F_RealName = userName,
                        ConnectionId = connectionId
                    });
                    //userName + "注册成功"
                    var msgModel = new MessageModel()
                    {
                        SendUserID = "systemId",
                        SendUserName = "system",
                        Msg = userName + "注册成功",
                        Type = MessageTypeEnum.System.GetHashCode()
                    };
                    hubClients.All.SendAsync(_registerUserthod, "system", msgModel);
                }
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "RegisterUser",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "RegisterUser",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
    }

    /// <summary>
    /// 加入案件组
    /// </summary>
    /// <param name="lawcaseId"></param>
    /// <param name="userId"></param>
    /// <returns></returns>
    public void JoinGroup(string lawcaseId, string userId)
    {
        try
        {
            if (!string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(lawcaseId))
            {
                if (lawcaseId.Contains(","))
                { 
                    var lawcaseIds = lawcaseId.Split(',').ToList();
                    foreach (var item in lawcaseIds)
                    {
                        if (!string.IsNullOrEmpty(item))
                        {
                            OnlineUserService.Instance.JoinGroup(item, userId);//, this.Groups
                        }
                    }
                }
                else
                {
                    OnlineUserService.Instance.JoinGroup(lawcaseId, userId);//, this.Groups
                }                    
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "JoinGroup",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "JoinGroup",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
    }

    /// <summary>
    /// 加入案件组(批量)
    /// </summary>
    /// <param name="lawcaseId"></param>
    /// <param name="userId"></param>
    /// <returns></returns>
    //public void JoinGroupBatch(string lawcaseId, string userId)
    //{
    //    try
    //    {
    //        if (!string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(lawcaseId))
    //        {
    //            OnlineUserService.Instance.JoinGroup(lawcaseId, userId);//, this.Groups
    //        }
    //    }
    //    catch (Exception ex)
    //    {
    //        //写日志
    //        ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
    //        {
    //            Search1 = "JoinGroup",
    //            Search2 = string.Empty,
    //            ClassName = _className,
    //            Method = "JoinGroup",
    //            Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
    //            RequestModel = string.Empty,
    //            ResponseModel = string.Empty,
    //            ElapsedTime = 0,
    //            Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
    //            InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
    //            ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
    //            ResultCode = 200,
    //            Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
    //            RowStatus = TrueOrFalseEnum.True.GetHashCode(),
    //            CreatedBy = "system",
    //            CreatedOn = DateTime.Now
    //        });
    //    }
    //}

    /// <summary>
    /// 移除案件组
    /// </summary>
    /// <param name="lawcaseId"></param>
    /// <param name="userId"></param>
    /// <returns></returns>
    public void RemoveGroup(string lawcaseId, string userId)
    {
        try
        {
            if (!string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(lawcaseId))
            {
                OnlineUserService.Instance.RemoveGroup(lawcaseId, userId);//, this.Groups
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "RemoveGroup",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "RemoveGroup",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
    }

    /// <summary>
    /// 私聊
    /// </summary>
    /// <param name="receiveUserId"></param>
    /// <param name="message"></param>
    /// <param name="sendUserId"></param>
    /// <param name="sendUserName"></param>
    /// <returns></returns>
    //public async Task SendPrivateMsg(string receiveUserId, string message, string sendUserId, string sendUserName)
    //{
    //    var hubClients = OnlineUserService.Instance.GetClient();
    //    if (hubClients != null && string.IsNullOrEmpty(receiveUserId) && string.IsNullOrEmpty(message))
    //    {
    //        var model = OnlineUserService.Instance.GetUserByUserId(receiveUserId);
    //        if (model != null)
    //        {
    //            //var t1 = _hubClients.User(model.ConnectionId).SendAsync(_receiveMsgmethod, new MessageModel() { UserID = sendUserId, Name = sendUserName, Msg = message, Direct = 1 });
    //            var t2 = model.HubClients.Client(model.ConnectionId).SendAsync(_receiveMsgmethod, sendUserId, message);//new MessageModel() { UserID = sendUserId, Name = sendUserName, Msg = message, Direct = 2 }
    //            //var t3 = this.InsertMessage(1, CurrentUserId, userId, message);
    //            //await Task.WhenAll(t1, t2, t3);
    //            await Task.WhenAll(t2);
    //        }
    //    }
    //}

    /// <summary>
    /// 给指定房间内所有用户发消息
    /// </summary>
    /// <param name="roomid"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    //public async Task SendGroupMessage(string roomid, string message)
    //{
    //    if (_hubClients != null)
    //    {
    //        var t1 = _hubClients.Group(roomid).SendAsync("ReceiveGroupMessage", new { UserID = CurrentUserId, Name = CurrentUserName, Msg = message });
    //        var t2 = this.InsertMessage(2, CurrentUserId, "", message);
    //        await Task.WhenAll(t1, t2);
    //    }
    //}
}
/// <summary>
/// 集线器
/// 在线用户库 (多服务器时要存在公共缓存中)
/// </summary>
public class OnlineUserService
{

    #region 属性成员

    private string _className = "OnlineUserService";

    /// <summary>
    /// 单例
    /// </summary>
    private static OnlineUserService _Instance = new OnlineUserService();

    /// <summary>
    /// 已连接的用户信息
    /// </summary>
    private Dictionary<string, IHubCallerClients> _OnlineUserClients { get; set; }// = new Dictionary<string, IHubCallerClients>();

    /// <summary>
    /// 在线用户
    /// </summary>
    private List<OnlineUserModel> _OnlineUser { get; set; }// = new List<OnlineUserModel>();

    /// <summary>
    /// 在线用户
    /// </summary>
    private Dictionary<string, List<OnlineUserModel>> _GroupList { get; set; }// = new Dictionary<string, List<OnlineUserModel>>();

    private static IHubCallerClients _hubClients;

    private System.Threading.Timer _timer = null;
    private static readonly object _lock = new object();

    /// <summary>
    /// 消息服务
    /// </summary>
    private static IMessageService _serviceMessage = new MessageService();

    /// <summary>
    /// 系统消息发送人
    /// </summary>
    private string _sendUser = "system";

    /// <summary>
    /// 前端接口接收消息的方法名
    /// </summary>
    private string _receiveMsgmethod = "chatHubReceiveMsg";

    /// <summary>
    /// 前端接口注册用户的方法名
    /// </summary>
    private string _registerUserthod = "chatHubRegisterUsert";

    /// <summary>
    /// 用户日程接口
    /// </summary>
    private IUserScheduleRemindService _userScheduleRemindService = null;
    /// <summary>
    /// 操作日志
    /// </summary>
    private IOperationLogService _operationLogService = null;
    /// <summary>
    /// 用户接口
    /// </summary>
    private IUserService _serviceUser = null;
    #endregion

    private OnlineUserService()
    {
        _OnlineUserClients = new Dictionary<string, IHubCallerClients>();
        _OnlineUser = new List<OnlineUserModel>();
        _GroupList = new Dictionary<string, List<OnlineUserModel>>();

        _userScheduleRemindService = new UserScheduleRemindService();
        _operationLogService = new OperationLogService();
        _serviceUser = ServiceLocator.Services.GetService<IUserService>();
    }

    /// <summary>
    /// 单例只读属性
    /// </summary>
    public static OnlineUserService Instance
    {
        get
        {
            return _Instance;
        }
    }

    /// <summary>
    /// 定时器
    /// </summary>
    /// <returns></returns>
    private void timerSend()
    {
        //System.Threading.Timer t = new System.Threading.Timer(SendMessageAsync, null, 0, 1000);
        if (_timer == null)
        {
            lock (_lock)
            {
                //需要处理的业务
                if (_timer == null)
                {
                    _timer = new System.Threading.Timer(sendRemindSchedule, null, 0, 60000);
                }
            }
        }
    }

    /// <summary>
    /// 根据用户ID获取Client对象
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns></returns>
    public IHubCallerClients GetClient(string userId = "")
    {
        IHubCallerClients clients = null;
        if (string.IsNullOrEmpty(userId))
        {
            clients = _hubClients;
        }
        else
        {
            var model = _OnlineUser.Find(t => t.F_Id.Equals(userId));
            if (model != null)
            {
                clients = model.HubClients;
            }
        }
        return clients;
    }

    /// <summary>
    /// 注册在线用户连接对象
    /// </summary>
    /// <param name="connectionId"></param>
    /// <param name="client"></param>
    /// <returns></returns>
    public bool AddClients(string connectionId, IHubCallerClients client)
    {
        var isSucceed = false;
        try
        {
            if (!string.IsNullOrEmpty(connectionId) && client != null)
            {
                _hubClients = client;
                if (!_OnlineUserClients.ContainsKey(connectionId))
                {
                    _OnlineUserClients.Add(connectionId, client);
                    timerSend();
                }
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "AddClients",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "AddClients",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_AddClients.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_AddClients,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return isSucceed;
    }

    /// <summary>
    /// 移除在线用户连接对象
    /// </summary>
    /// <param name="connectionId"></param>
    /// <returns></returns>
    public bool RemoveClients(string connectionId)
    {
        var isSucceed = false;
        try
        {
            if (!string.IsNullOrEmpty(connectionId))
            {
                if (_OnlineUserClients.ContainsKey(connectionId))
                {
                    //从在线用户连接客户端集合中删除用户
                    _OnlineUserClients.Remove(connectionId);
                    if (_OnlineUserClients.Count == 0)
                    {
                        _hubClients = null;
                        _timer = null;
                    }
                    //从在用户集合中删除用户
                    var userModel = _OnlineUser.FirstOrDefault(t => t.ConnectionId.Equals(connectionId));
                    if (userModel != null)
                    {
                        _OnlineUser.Remove(userModel);
                        isSucceed = true;
                    }
                    //从组中删除用户
                    foreach (var item in _GroupList)
                    {
                        if (item.Value != null)
                        {
                            var groupUserModel = item.Value.FirstOrDefault(t => !string.IsNullOrEmpty(t.ConnectionId) && t.ConnectionId.Equals(connectionId));
                            if (groupUserModel != null)
                            {
                                item.Value.Remove(groupUserModel);
                                isSucceed = true;
                            }
                        }
                    }
                    //发送连接成功消息
                    var msg = string.Format("【{0}】已下线,uid:{1}", userModel.F_RealName, userModel.ConnectionId);
                    SendPublicMsg("chatHubConnectResponse", msg, _sendUser, _sendUser);
                }
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "RemoveClients",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "RemoveClients",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RemoveClients.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RemoveClients,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return isSucceed;
    }

    /// <summary>
    /// 注册在线用户
    /// </summary>
    /// <param name="userModel"></param>
    /// <returns></returns>
    public bool AddOnlineUser(OnlineUserModel userModel)
    {
        var isSucceed = false;
        try
        {
            if (userModel != null)
            {
                var userObj = _serviceUser.GetById(userModel.F_Id);
                if (userObj != null)
                {
                    userModel.F_RealName = userObj.F_RealName;
                }
                var model = _OnlineUser.FirstOrDefault(t => t.F_Id == userModel.F_Id);
                if (model == null)
                {
                    if (_OnlineUserClients.ContainsKey(userModel.ConnectionId))
                    {
                        userModel.HubClients = _OnlineUserClients[userModel.ConnectionId];
                    }
                    _OnlineUser.Add(userModel);

                }
                else
                {
                    _OnlineUser.Remove(userModel);
                    if (_OnlineUserClients.ContainsKey(userModel.ConnectionId))
                    {
                        userModel.HubClients = _OnlineUserClients[userModel.ConnectionId];
                    }
                    _OnlineUser.Add(userModel);
                }
                isSucceed = true;
                //发送连接成功消息
                var msg = string.Format("【{0}】连接成功,uid:{1}", userModel.F_RealName, userModel.ConnectionId);
                SendPublicMsg("chatHubConnectResponse", msg, _sendUser, _sendUser);
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "AddOnlineUser",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "AddOnlineUser",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return isSucceed;
    }

    /// <summary>
    /// 移除在线用户
    /// </summary>
    /// <param name="userModel"></param>
    /// <returns></returns>
    public bool RemoveOnlineUser(OnlineUserModel userModel)
    {
        var isSucceed = false;
        try
        {
            if (userModel != null)
            {
                var model = _OnlineUser.Find(t => t.F_Id == userModel.F_Id);
                if (model != null)
                {
                    isSucceed = _OnlineUser.Remove(userModel);
                    isSucceed = _OnlineUserClients.Remove(model.ConnectionId);
                }
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "RemoveOnlineUser",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "RemoveOnlineUser",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return isSucceed;
    }

    /// <summary>
    ///  加入案件组
    /// </summary>
    /// <param name="lawcaseId"></param>
    /// <param name="userId"></param>
    /// <returns></returns>
    public bool JoinGroup(string lawcaseId, string userId)//, IGroupManager Groups
    {
        var isSucceed = false;
        try
        {
            if (!string.IsNullOrEmpty(lawcaseId) && !string.IsNullOrEmpty(userId))
            {
                var userName = string.Empty;
                if (_GroupList.ContainsKey(lawcaseId))
                {
                    //组存在
                    var model = _OnlineUser.FirstOrDefault(t => t.F_Id == userId);
                    if (model != null)
                    {
                        //将客户端的连接ID加入到组里面
                        //Groups.AddToGroupAsync(model.ConnectionId, lawcaseId);
                        userName = model.F_RealName;
                        var userList = _GroupList[lawcaseId];
                        if (userList != null)
                        {
                            userList = userList.FindAll(t => t != null);
                            var userModel = userList.FirstOrDefault(t => t.F_Id.Equals(userId));
                            if (userModel == null)
                            {
                                userList.Add(model);
                                _GroupList[lawcaseId] = userList;
                            }
                        }
                    }
                }
                else
                {
                    var model = _OnlineUser.Find(t => t.F_Id == userId);
                    if (model != null)
                    {
                        userName = model.F_RealName;
                        //将客户端的连接ID加入到组里面
                        //Groups.AddToGroupAsync(model.ConnectionId, lawcaseId);

                        _GroupList.Add(lawcaseId, new List<OnlineUserModel>() { model });
                        isSucceed = true;
                    }
                }
                var tasl = SendPrivateMsg(userId, userName, userName + "用户加入案件组成功", _sendUser, _sendUser);
                //tasl.Wait();
                isSucceed = true;
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "JoinGroup",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "JoinGroup",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = "加入案件组",
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return isSucceed;
    }

    /// <summary>
    /// 退出案件组
    /// </summary>
    /// <param name="lawcaseId"></param>
    /// <param name="userId"></param>
    /// <returns></returns>
    public bool RemoveGroup(string lawcaseId, string userId)//, IGroupManager Groups
    {
        var isSucceed = false;
        try
        {
            if (!string.IsNullOrEmpty(lawcaseId) && !string.IsNullOrEmpty(userId))
            {
                if (_GroupList.ContainsKey(lawcaseId))
                {
                    var userList = _GroupList[lawcaseId];
                    if (userList != null)
                    {
                        var userModel = userList.FirstOrDefault(t => t.F_Id.Equals(userId));
                        if (userModel == null)
                        {
                            isSucceed = userList.Remove(userModel);
                            //Groups.RemoveFromGroupAsync(userModel.ConnectionId, lawcaseId);
                            var tasl = SendPrivateMsg(userId, userModel.F_RealName, userModel.F_RealName + "用户退出案件组", _sendUser, _sendUser);
                            //tasl.Wait();
                        }
                        else
                        {
                            //Clients.Client(Context.ConnectionId).showMessage("该房间不存在");
                            var tasl = SendPrivateMsg(userId, userModel.F_RealName, "该用户不在案件组中", _sendUser, _sendUser);
                            //tasl.Wait();
                        }
                    }
                }
                //else
                //{
                //    var tasl = SendPrivateMsg(userId, "该房间不存在", _sendUser, _sendUser);
                //    tasl.Wait();
                //}
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "RemoveGroup",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "RemoveGroup",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return isSucceed;
    }

    /// <summary>
    /// 根扰连接ID获取在线用户对象
    /// </summary>
    /// <param name="connectionId"></param>
    /// <returns></returns>
    public OnlineUserModel GetUserByConnectionId(string connectionId)
    {
        OnlineUserModel model = null;
        try
        {
            if (!string.IsNullOrEmpty(connectionId))
            {
                model = _OnlineUser.Find(t => t.ConnectionId == connectionId);
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "GetUserByConnectionId",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "GetUserByConnectionId",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return model;
    }

    /// <summary>
    /// 根扰连接ID获取在线用户对象
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    public OnlineUserModel GetUserByUserId(string userId)
    {
        OnlineUserModel model = null;
        try
        {
            if (!string.IsNullOrEmpty(userId))
            {
                model = _OnlineUser.Find(t => t.F_Id == userId);
            }
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "GetUserByUserId",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "GetUserByUserId",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = string.Empty,
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }
        return model;
    }

    /// <summary>
    /// 公共消息
    /// </summary>
    /// <param name="message"></param>
    /// <param name="sendUserId"></param>
    /// <param name="sendUserName"></param>
    /// <returns></returns>
    public bool SendPublicMsg(string message, string sendUserId, string sendUserName)
    {
        // 后期考虑后台管理添加系统通知,这里来查 通知到链接的人
        var isSucceed = false;
        var hubClients = GetClient();
        if (hubClients != null)
        {
            if (string.IsNullOrEmpty(sendUserName))
            {
                sendUserName = _sendUser;
            }
            var msgModel = new MessageModel()
            {
                SendUserID = sendUserId,
                SendUserName = sendUserName,
                Msg = message,
                Type = MessageTypeEnum.System.GetHashCode()
            };
            var t1 = hubClients.All.SendAsync(_receiveMsgmethod, sendUserName, msgModel);// new { Msg = message, Direct = 0 }
            this.InsertMessage(0, sendUserId, sendUserName, "ALL", "ALL", message); //添加历史记录
            isSucceed = true;
            //await Task.WhenAll(t1);
        }
        return isSucceed;
    }

    /// <summary>
    /// 公共消息
    /// </summary>
    /// <param name="message"></param>
    /// <param name="sendUserId"></param>
    /// <param name="sendUserName"></param>
    /// <returns></returns>
    public bool SendPublicMsg(string method, string message, string sendUserId, string sendUserName)
    {
        // 后期考虑后台管理添加系统通知,这里来查 通知到链接的人
        var isSucceed = false;
        var hubClients = GetClient();
        if (hubClients != null)
        {
            if (string.IsNullOrEmpty(sendUserName))
            {
                sendUserName = _sendUser;
            }
            var msgModel = new MessageModel()
            {
                SendUserID = sendUserId,
                SendUserName = sendUserName,
                Msg = message,
                Type = MessageTypeEnum.System.GetHashCode()
            };
            var t1 = hubClients.All.SendAsync(method, sendUserName, msgModel);// new { Msg = message, Direct = 0 }
            this.InsertMessage(0, sendUserId, sendUserName, "ALL", "ALL", message); //添加历史记录
            isSucceed = true;
            //await Task.WhenAll(t1);
        }
        return isSucceed;
    }

    /// <summary>
    /// 私聊
    /// </summary>
    /// <param name="receiveUserId">接收人ID</param>
    /// <param name="receiveUserName">接收人姓名</param>
    /// <param name="message">发送的消息</param>
    /// <param name="sendUserId">发送人ID</param>
    /// <param name="sendUserName">发送人姓名</param>
    /// <returns></returns>
    public bool SendPrivateMsg(string receiveUserId, string receiveUserName, string message, string sendUserId, string sendUserName)
    {
        var isSucceed = false;
        var hubClients = GetClient(receiveUserId);
        if (hubClients != null && !string.IsNullOrEmpty(receiveUserId) && !string.IsNullOrEmpty(message))
        {
            var model = GetUserByUserId(receiveUserId);
            if (model != null)
            {
                //model.HubClients.Client(model.ConnectionId) ok
                //var t2 = model.HubClients.Client(model.ConnectionId).SendAsync(_receiveMsgmethod, sendUserName, message);//new MessageModel() { UserID = sendUserId, Name = sendUserName, Msg = message, Direct = 2 }
                //hubClients.Client(model.ConnectionId) ok
                //var t1 = hubClients.Client(model.ConnectionId).SendAsync(_receiveMsgmethod, sendUserName, message);//
                var msgModel = new MessageModel()
                {
                    SendUserID = sendUserId,
                    SendUserName = sendUserName,
                    Msg = message,
                    Type = MessageTypeEnum.SendMsg.GetHashCode()
                };
                var t1 = hubClients.Client(model.ConnectionId).SendAsync(_receiveMsgmethod, sendUserName, msgModel);
                this.InsertMessage(1, sendUserId, sendUserName, receiveUserId, receiveUserName, message);
                //await Task.WhenAll(t1);
                isSucceed = true;
            }
        }
        return isSucceed;
    }

    /// <summary>
    /// 私聊
    /// </summary>
    /// <param name="receiveUserId">接收人ID</param>
    /// <param name="receiveUserName">接收人姓名</param>
    /// <param name="message">发送的消息</param>
    /// <param name="sendUserId">发送人ID</param>
    /// <param name="sendUserName">发送人姓名</param>
    /// <returns></returns>
    public bool SendPrivateMsg(string receiveUserId, string receiveUserName, MessageModel message, string sendUserId, string sendUserName)
    {
        var isSucceed = false;
        var hubClients = GetClient(receiveUserId);
        if (hubClients != null && !string.IsNullOrEmpty(receiveUserId) && message != null)
        {
            var model = GetUserByUserId(receiveUserId);
            if (model != null)
            {
                var t1 = hubClients.Client(model.ConnectionId).SendAsync(_receiveMsgmethod, sendUserName, message);
                this.InsertMessage(1, sendUserId, sendUserName, receiveUserId, receiveUserName, JsonConvert.SerializeObject(message));
                //await Task.WhenAll(t1);
                isSucceed = true;
            }
        }
        return isSucceed;
    }

    /// <summary>
    /// 给指定房间内所有用户发消息
    /// </summary>
    /// <param name="groupId">房间ID(组ID)</param>
    /// <param name="message">发送的消息</param>
    /// <param name="sendUserId">发送人ID</param>
    /// <param name="sendUserName">发送姓名</param>
    /// <returns></returns>
    public bool SendGroupMsg(string groupId, string message, string sendUserId, string sendUserName)
    {
        var isSucceed = false;
        if (_hubClients != null && _GroupList.ContainsKey(groupId))
        {
            var msgModel = new MessageModel()
            {
                SendUserID = sendUserId,
                SendUserName = sendUserName,
                Msg = message,
                Type = MessageTypeEnum.SendMsg.GetHashCode()
            };
            var t1 = _hubClients.Group(groupId).SendAsync(_receiveMsgmethod, "Group(groupId):" + msgModel);
            //t1.Wait();
            var groupUserList = _GroupList[groupId];
            if (groupUserList != null && groupUserList.Count > 0)
            {
                groupUserList = groupUserList.FindAll(t => t != null && !string.IsNullOrEmpty(t.ConnectionId));
                foreach (var item in groupUserList)
                {
                    var t11 = SendPrivateMsg(item.F_Id, item.F_RealName, msgModel.Msg, sendUserId, sendUserName);
                    this.InsertMessage(2, sendUserId, sendUserName, item.F_Id, item.F_RealName, message);
                    //await Task.WhenAll(t11);
                }
                isSucceed = true;
            }
        }
        return isSucceed;
    }

    /// <summary>
    /// 保存消息记录
    /// </summary>
    /// <param name="type"></param>
    /// <param name="sendUserId"></param>
    /// <param name="sendUserName"></param>
    /// <param name="receiveUserId"></param>
    /// <param name="receiveUserName"></param>
    /// <param name="msg"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    private bool InsertMessage(int type, string sendUserId, string sendUserName, string receiveUserId, string receiveUserName, string msg)
    {
        var isOk = false;
        try
        {
            var msgModel = new Message();
            msgModel.Id = Guid.NewGuid().ToString("N");
            msgModel.Type = type;
            msgModel.SendUserId = sendUserId;
            msgModel.SendUserName = sendUserName;
            msgModel.ReceiveUserId = receiveUserId;
            msgModel.ReceiveUserName = receiveUserName;
            msgModel.MsgContent = msg;
            msgModel.IsRead = TrueOrFalseEnum.False.GetHashCode();
            msgModel.RowStatus = TrueOrFalseEnum.True.GetHashCode();
            msgModel.Remark = string.Empty;
            msgModel.CreatedOn = DateTime.Now;
            msgModel.CreatedBy = sendUserId;
            msgModel.UpdatedBy = string.Empty;
            msgModel.UpdatedOn = SystemConst.DateTimeDefault;

            //await SqlDapperHelper.ExecuteInsertAsync(msg);
            isOk = _serviceMessage.AddModel(msgModel);
        }
        catch (Exception ex)
        {
            //写日志
            ApiLogQueueService.Instance.Enqueue(new ApiLogServiceModel()
            {
                Search1 = "InsertMessage",
                Search2 = string.Empty,
                ClassName = _className,
                Method = "InsertMessage",
                Type = ex == null ? ApiLogType.Common.GetHashCode() : ApiLogType.Error.GetHashCode(),
                RequestModel = string.Empty,
                ResponseModel = "保存消息记录",
                ElapsedTime = 0,
                Code = InterfaceName.ChatHub_RegisterUser.GetHashCode(),
                InterfaceNameEnum = InterfaceName.ChatHub_RegisterUser,
                ProjectId = ProjectIdEnum.LDApi.GetHashCode(),
                ResultCode = 200,
                Remark = ex != null ? string.Format("errorMsg:{0},Exception:{1}", ex.Message, ex.ToString()) : string.Empty,
                RowStatus = TrueOrFalseEnum.True.GetHashCode(),
                CreatedBy = "system",
                CreatedOn = DateTime.Now
            });
        }

        return isOk;
    }

    /// <summary>
    /// 发送日程提醒
    /// </summary>
    /// <param name="obj"></param>
    private void sendRemindSchedule(object obj)
    {
        try
        {
            //获取需要此人需要提醒的日程 
            DateTime startTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:00"));
            DateTime endTime = startTime.AddMinutes(5);

            //发送测试消息
            //var msg = "[" + CommonHelp.ServiceIp + "]系统消息:现在是" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            //SendPublicMsg(msg, _sendUser, _sendUser);

            foreach (var item in _OnlineUser)
            {
                if (item != null && !string.IsNullOrEmpty(item.F_Id))
                {
                    var remindScheduleList = _userScheduleRemindService.GetRemindSchedule(item.F_Id, startTime, endTime);
                    foreach (var itemRemindSchedule in remindScheduleList)
                    {
                        // IpAddress:日程ID      Time:(2 天前 · 日历 · 2021年12月28日 16:00 - 2021年12月28日 18:00)
                        var timestr = Common.DateStringFromNow(itemRemindSchedule.RemindTime) + "· 日历 ·" + itemRemindSchedule.F_StartTime.ToString("yyyy年MM月dd日 HH:00") + " - " + itemRemindSchedule.F_EndTime.ToString("yyyy年MM月dd日 HH:00");
                        var msgModel = new MessageModel()
                        {
                            SendUserID = item.F_Id,
                            SendUserName = item.F_RealName,
                            Time = timestr,
                            Msg = itemRemindSchedule.F_Title,
                            SendTime = DateTime.Now.ToDateTimeString(),
                            F_Id = itemRemindSchedule.ReminbId.ToString(),
                            Type = MessageTypeEnum.ScheduleRemindMsg.GetHashCode()
                        };
                        var t = SendPrivateMsg(item.F_Id, item.F_RealName, msgModel, _sendUser, _sendUser);
                        //t.Wait();
                        //标记为已提醒
                        _userScheduleRemindService.UpdateRemind(itemRemindSchedule.ReminbId, itemRemindSchedule.IsEdit);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            _operationLogService.AddLogError(_className, "sendRemindSchedule", ex.Message, ex);
        }
    }
}

调用实例

/// <summary>
/// 新建案件事务 提交
/// </summary>
/// <param name="pinfo"></param>
/// <returns></returns>
[HttpPost]
[NoLDAPPLoginFilter]
public AjaxResult SubmitLawcase([FromBody] SubmitLawcaseViewModel pinfo)
{
    var sw = new Stopwatch();
    sw.Start();
    Exception exception = null;
    var rspModel = new AjaxResult();
    var loginUserId = CurrentUserId;
    try
    {
        var result = _serviceLawcase.SubmitLawcase(loginUserId, pinfo);
        if (!result.Item1)
        {
            return Error(result.Item2);
        }
        var lawcaseId = result.Item2;
        if (pinfo.JoinList != null && pinfo.JoinList.Count > 0)
        {
            //获取案由
            string causename = "";
            if(!string.IsNullOrEmpty(pinfo.CauseId))
            {
                var causeModel = _serviceCause.GetById(pinfo.CauseId);
                causename = causeModel.F_Name;
            }
            else
            {
                causename = pinfo.InputCause;

            }
            
            foreach (var item in pinfo.JoinList)
            {
                OnlineUserService.Instance.JoinGroup(lawcaseId, item.UserId);
            }
            //var sendMsg = string.Format("{0}案件创建成功", causeModel != null ? causeModel.F_Name : pinfo.Desc);
            var sendMsg = string.Format("{0}案件创建成功", causename);
            var task = OnlineUserService.Instance.SendGroupMsg(lawcaseId, sendMsg, loginUserId, CurrentUserName);
            //task.Wait();
        }
        //return Success(lawcaseId);
        rspModel.Success(lawcaseId);
    }
    catch (System.Exception ex)
    {
        //rspModel.Error("用户登录出错:", ex.Message);
        exception = ex;
        LogFactory.GetLogger("SubmitLawcase").Info("报错" + ex.Message);
        //return Error("新建案件事务 提交报错" + ex.Message);
    }
    AddLogElapsedTime(InterfaceName.Lawcase_SubmitLawcase, _className, "SubmitLawcase", pinfo, rspModel, rspModel.state, sw, exception, loginUserId);
    return rspModel;
}

 Startup 中注册

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
        IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
{    var apiUrlConfig = Configuration.GetSection("ApiUrl").Value;
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await Task.Run(() => { context.Response.Redirect("/index.html"); });
        });
        endpoints.MapControllers();
        //endpoints.MapHub<ServerHub>("/serverHub").RequireCors(t => t.WithOrigins(new string[] { apiUrlConfig }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
        endpoints.MapHub<ChatHub>("/chatHub").RequireCors(t => t.WithOrigins(new string[] { apiUrlConfig }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
        //endpoints.MapHub<ChatHub>("/serverHub").RequireCors(t => t.WithOrigins(new string[] { apiUrlConfig }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
        //endpoints.MapHub<ServerHub>("/serverHub").RequireCors(t => t.WithOrigins(new string[] { apiUrlConfig }).AllowAnyMethod().AllowAnyHeader().AllowCredentials());
    });
}