asp.net core 2.0 webapi集成signalr

在博客園也不少年了,一直不曾分享過什麼東西,也沒有寫過博客,但本身也是汲取着博客園的知識成長的;jquery

這兩天想着不能這麼無私,最近.NET CORE貌似挺流行的,閒來無事也本身搞了個asp.net core signalrweb

博客園裏面也有人在.net core 2.0下面集成了signalr,可是是集成在同一個項目裏面的,可是你們都知道咱們不少的項目都是分離的;json

並且signalr涉及到鏈接數和內存資源的佔用問題,若是都集成在一個項目裏面當訪問量多大的時候容易形成網站訪問緩慢,具體緣由就很少說了api

因此我這裏作了一個在.net core webapi裏面集成signalr,咱們就能夠經過調用webapi來實現服務器向客戶端推送消息跨域

第一步引用nuget:Mrcrosoft.AspNetCore.SignalR服務器

 

第二步添加配置代碼:app

首先ConfigureServices裏面添加以下代碼:asp.net

public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
            services.AddCors(options =>
            {
                options.AddPolicy("SignalrCore",
                    policy => policy.AllowAnyOrigin()
                                    .AllowAnyHeader()
                                    .AllowAnyMethod());
            });
            services.AddSingleton<IServiceProvider, ServiceProvider>();
        }

而後Configure裏面添加ide

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

            app.UseMvc();
        }

 

而後咱們添加一個hubs優化

public class SignalrHubs:Hub
    {
        /// <summary>
        /// 建立signalr連接
        /// </summary>
        /// <param name="parentId">pid(做爲用戶組)</param>
        /// <param name="shopId">sid</param>
        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<SignalrHubs> hubContext;
        public MRSoftPushController(IServiceProvider service)
        {
            hubContext = service.GetService<IHubContext<SignalrHubs>>();
        }

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

        /// <summary>
        /// 單個connectionid推送
        /// </summary>
        /// <param name="groups"></param>
        /// <returns></returns>
        [HttpPost,Route("AnyOne")]
        public IActionResult AnyOne([FromBody]IEnumerable<SignalrGroups> 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();
        }

        /// <summary>
        /// 所有推送
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [HttpGet,Route("EveryOne")]
        public IActionResult EveryOne(string message)
        {
            hubContext.Clients.All.InvokeAsync("EveryOne", $"{message}");
            return Ok();
        }

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

        /// <summary>
        /// 多參數接收方式
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [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();
        }
    }

服務器端的代碼到這裏所有完成,接下來我們看客戶端的代碼

個人客戶端代碼是在另一個項目裏面,和服務器端是分離的

<input type="text" id="ParentId" placeholder="ParentId" />
<br />
<input type="text" id="ShopId" placeholder="ShopId" />
<br />
<button id="fuckyou">用戶上線</button>
<br />
<br />
<br />

<ul id="message" style="color:red;"></ul>

@section scripts {
    <script>
        $(function () {

            let hubUrl = 'http://192.168.0.149:8009/signalrHubs';
            let httpConnection = new signalR.HttpConnection(hubUrl);
            let hubConnection = new signalR.HubConnection(httpConnection);
            $("#fuckyou").click(function () {
                hubConnection.invoke('InitUser', $("#ParentId").val(), $("#ShopId").val());
            });
            hubConnection.on('NoticeOnline', data => {
                $("#message").append("<li>" + data + "</li>");
            });
            hubConnection.on('EveryOne', data => {
                $("#message").append("<li style=\"color:red;\">所有推送:" + data + "</li>");
            });
            hubConnection.on('AnyGroups', data => {
                $("#message").append("<li style=\"color:black;\">單個用戶組推送:" + data + "</li>");
            });
            hubConnection.on('AnyOne', data => {
                $("#message").append("<li style=\"color:blue;\">單個ID推送:" + data + "</li>");
            });
            hubConnection.on('MoreParamsRequest', (message, date) => {
                $("#message").append("<li style=\"color:green;\">多參數接收:" + message + " : " + data + "</li>");
            });
            hubConnection.start();

        });
    </script>
}

頁面上引用連個js

<script src="/js/signalr-client.min.js"></script>
<script src="/js/jquery.min.js"></script>

 

到這裏基本就已經完成了,下面看一下運行效果

 

第一次寫博客,有點緊張,代碼寫得比較倉促,不少細節都沒有優化,有不少不足之處,望各位多多指正

相關文章
相關標籤/搜索