zoukankan      html  css  js  c++  java
  • .net mvc中SignalR的使用配置

    安装Microsoft.AspNet.SignalR(使用的版本2.4.1)

    新建Hubs文件夹:Hub的接口和实现

    namespace SingralRedis.Hubs
    {
        interface IChatHub
        {
            //服务器下发消息到各个客户端
            void SendChat(string id, string name, string message);
    
            //用户上线通知
            void SendLogin(string id, string name);
    
            //用户下线通知
            void SendLogoff(string id, string name);
    
            //接收客户端发送的心跳包并处理
            void TriggerHeartbeat(string id, string name);
        }
    }
    IChatHub

    提供五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect.

    这里只 override OnConnected,看需要重载

    using Microsoft.AspNet.SignalR;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Timers;
    
    
    namespace SingralRedis.Hubs
    {
        public class ChatHub : Hub,IChatHub
        {
    
            public override System.Threading.Tasks.Task OnConnected()
            {
    
                string userName = Context.QueryString["userName"]; //获取客户端发送过来的用户名
                string userId = Context.QueryString["userId"]; //获取客户端发送过来的用户名
                string connectionId = Context.ConnectionId;
                if (!string.IsNullOrEmpty(userId))
                {
                    SendLogin(userId, userName, connectionId);
                }
                //HttpContext.Current.Application.Add(userName, connectionId); //存储关系
                return base.OnConnected();
            }
            public class UserChat
            {
                public UserChat()
                {
                    Count = 0;
                    if (Timer == null) Timer = new Timer();
                    Timer.Interval = 1000;  //1s触发一次
                    Timer.Start();
                    Timer.Elapsed += (sender, args) =>
                    {
                        Count++;
                        if (Count >= 20)
                        {
                            action();  //该用户掉线了,抛出事件通知
                            Timer.Stop();
                        }
                    };
                }
    
                private readonly Timer Timer;
                public event Action action;
                //public event Action action1;
    
                public string UserId { get; set; }
                public string ID { get; set; }
                public string Name { get; set; }
    
                //内部计数器(每次递增1),如果服务端每5s能收到客户端的心跳包,那么count被重置为0;
                //如果服务端20s后仍未收到客户端心跳包,那么视为掉线
                public int Count { get; set; }
            }
    
            public static class ChatUserCache
            {
                public static IList<UserChat> userList = new List<UserChat>();
            }
    
            private IList<UserChat> userList = ChatUserCache.userList;       
           
            /// <summary>
            /// 推送个单个用户
            /// </summary>
            /// <param name="name">用户名</param>
            public void SendToUser(string name)
            {
                //根据username获取对应的ConnectionId
                var user = userList.FirstOrDefault(v => v.Name == name);
                if (user != null)
                {
                    Clients.Client(user.UserId).addNewMessageToPage("新的信息");
                }
            }
    
            /// <summary>
            /// 自发自收
            /// </summary>
            public void ReturnId()
            {
                Clients.Caller.CheckId(Context.ConnectionId);
            }    
    
            /// <summary>
            /// 获取全部用户
            /// </summary>
            public void GetAllUserList()
            {
                Clients.All.loginUser(userList);
            }
    
    
    
            public void SendChat(string id, string name, string message)
            {
                Clients.Client(id).GetChatMsg("<====用户 " + name +" 发送消息 "+ message+" ======>");
                
            }
    
            public void SendLogin(string id, string name, string connectionId)
            {
                connectionId = string.IsNullOrEmpty(connectionId) ? connectionId = Context.ConnectionId : connectionId;
    
                if (!userList.Any(v => v.ID == id))
                {
                    var userInfo = new UserChat() { UserId = connectionId, ID = id, Name = name };
                    userInfo.action += () =>
                    {
                        //用户20s无心跳包应答,则视为掉线,会抛出事件,这里会接住,然后处理用户掉线动作。
                        SendLogoff(id, name);
                    };
                    userList.Add(userInfo);
                }
                else
                {
                    var user = userList.FirstOrDefault(v => v.ID == id);
                    user.UserId = connectionId;
                    user.Count = 0;
                }
                Clients.All.loginUser(userList);
                
            }
    
            public void SendLogoff(string id, string name)
            {
                var userInfo = userList.Where(x => x.ID.Equals(id) && x.Name.Equals(name)).FirstOrDefault();
                if (userInfo != null)
                {
                    var name1 = userInfo.Name;
    
                    if (userList.Remove(userInfo))
                    {
                        Clients.All.logoffUser(userList);
    
    
                        SendChat(id, name, "<====用户 " + name + " 退出了讨论组====>");
                    }
                }
            }
    
            public void TriggerHeartbeat(string id, string name)
            {
                var userInfo = userList.Where(x => x.ID.Equals(id) && x.Name.Equals(name)).FirstOrDefault();
                if (userInfo != null)
                {
                    userInfo.Count = 0;  //收到心跳,重置计数器
                }
            }
        }
    }
    ChatHub

    新建Startup.cs文件

    using Owin;
    
    namespace SingralRedis
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Any connection or hub wire up and configuration should go here
    //会默认指定一个路径  "/signalr" 
    app.MapSignalR(); } } }
  • 相关阅读:
    springboot事务注解@Transactional
    Springboot + mybatis + React+redux+React-router+antd+Typescript(三): 上线
    Springboot + mybatis + React+redux+React-router+antd+Typescript(二): React+Typescrip项目的搭建
    Springboot + mybatis + React+redux+React-router+antd+Typescript(一): 后台Springboot+Mybatis的搭建
    spring(四):spring与mybatis结合
    spring(三):springAOP的各种织入方式一览
    spring(二):简单阐述springAOP的实现原理
    spring(一):spring IoC的注入方式总结
    java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件
    java web(六):mybatis之一对一、一对多、多对多映射
  • 原文地址:https://www.cnblogs.com/zhuzy/p/12187581.html
Copyright © 2011-2022 走看看