asp.net core 2.0 webapi集成signalr

2021-04-26 09:26

阅读:359

 

在博客园也很多年了,一直未曾分享过什么东西,也没有写过博客,但自己也是汲取着博客园的知识成长的;

这两天想着不能这么无私,最近.NET CORE貌似挺流行的,闲来无事也自己搞了个asp.net core signalr

博客园里面也有人在.net core 2.0下面集成了signalr,但是是集成在同一个项目里面的,但是大家都知道我们很多的项目都是分离的;

而且signalr涉及到连接数和内存资源的占用问题,如果都集成在一个项目里面当访问量多大的时候容易造成网站访问缓慢,具体原因就不多说了

所以我这里做了一个在.net core webapi里面集成signalr,我们就可以通过调用webapi来实现服务器向客户端推送消息

第一步引用nuget:Mrcrosoft.AspNetCore.SignalR

 

第二步添加配置代码:

首先ConfigureServices里面添加如下代码:

技术分享图片
public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
            services.AddCors(options =>
            {
                options.AddPolicy("SignalrCore",
                    policy => policy.AllowAnyOrigin()
                                    .AllowAnyHeader()
                                    .AllowAnyMethod());
            });
            services.AddSingleton();
        }
技术分享图片

然后Configure里面添加

技术分享图片
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //跨域支持
            app.UseCors("SignalrCore");
            app.UseSignalR(routes =>
            {
                routes.MapHub("signalrHubs");
            });
            app.UseWebSockets();

            app.UseMvc();
        }
技术分享图片

 

然后我们添加一个hubs

技术分享图片
public class SignalrHubs:Hub
    {
        /// 
        /// 创建signalr链接
        /// 
        /// pid(作为用户组)
        /// sid
        public Task InitUser(string parentId, string shopId)
        {
            Groups.AddAsync(Context.ConnectionId, parentId);
            SignalrGroups.UserGroups.Add(new SignalrGroups()
            {
                ConnectionId = Context.ConnectionId,
                GroupName = parentId,
                ShopId = shopId
            });
            return Clients.All.InvokeAsync("NoticeOnline", "用户组数据更新完成,新增id为:" + Context.ConnectionId + " pid:" + parentId + "   sid:" + shopId + "");
        }

        public override Task OnDisconnectedAsync(Exception exception)
        {
            //掉线移除用户
            var user = SignalrGroups.UserGroups.FirstOrDefault(c => c.ConnectionId == Context.ConnectionId);
            if (user != null)
            {
                SignalrGroups.UserGroups.Remove(user);
                Groups.RemoveAsync(Context.ConnectionId, user.GroupName);
            }
            return base.OnDisconnectedAsync(exception);
        }
    }
技术分享图片

PS:我这里是根据本人业务需要来做的,大家可以修改成其他的(用户量大的时候内存占用肯定高,这里只做一个简单的例子)

以上基本的环境搭建就已经完成了

接下来控制器里面的代码

技术分享图片
[Produces("application/json")]
    [Route("api/MRSoftPush")]
    public class MRSoftPushController : Controller
    {
        private IHubContext hubContext;
        public MRSoftPushController(IServiceProvider service)
        {
            hubContext = service.GetService>();
        }

        [HttpGet]
        public string Get()
        {
            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff");
        }

        /// 
        /// 单个connectionid推送
        /// 
        /// 
        /// 
        [HttpPost,Route("AnyOne")]
        public IActionResult AnyOne([FromBody]IEnumerable groups)
        {
            if (groups != null && groups.Any())
            {
                var ids = groups.Select(c=>c.ShopId);
                var list = SignalrGroups.UserGroups.Where(c=>ids.Contains(c.ShopId));
                foreach (var item in list)
                    hubContext.Clients.Client(item.ConnectionId).InvokeAsync("AnyOne", $"{item.ConnectionId}: {item.Content}");
            }
            return Ok();
        }

        /// 
        /// 全部推送
        /// 
        /// 
        /// 
        [HttpGet,Route("EveryOne")]
        public IActionResult EveryOne(string message)
        {
            hubContext.Clients.All.InvokeAsync("EveryOne", $"{message}");
            return Ok();
        }

        /// 
        /// 组推送
        /// 
        /// 
        /// 
        [HttpPost,Route("AnyGroups")]
        public IActionResult AnyGroups([FromBody]SignalrGroups group)
        {
            if (group != null)
            {
                hubContext.Clients.Group(group.GroupName).InvokeAsync("AnyGroups", $"{group.Content}");
            }
            return Ok();
        }

        /// 
        /// 多参数接收方式
        /// 
        /// 
        /// 
        [HttpGet,Route("MoreParamsRequest")]
        public IActionResult MoreParamsRequest(string message)
        {
            hubContext.Clients.All.InvokeAsync("MoreParamsRequest", message, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"));
            return Ok();
        }
    }
技术分享图片

服务器端的代码到这里全部完成,接下来咱们看客户端的代码

我的客户端代码是在另外一个项目里面,和服务器端是分离的

技术分享图片





    @section scripts { }
    技术分享图片

    页面上引用连个js


     

    到这里基本就已经完成了,下面看一下运行效果

    技术分享图片

     

    第一次写博客,有点紧张,代码写得比较仓促,很多细节都没有优化,有很多不足之处,望各位多多指正

     


    评论


    亲,登录后才可以留言!