netcore3.1 webapi使用signalR


前言
  今天嘗試了一下signalR,感覺還不錯,因為暫時用不到,就寫一篇博文來記錄搭建過程,以免以后給忘了,基於官方文檔寫的,不過官方沒有webapi調用例子,就自己寫了一下,大神勿噴

使用
1.創建一個netcore3.1 webapi程序,nuget引用一下Microsoft.AspNetCore.SignalR,我這里是1.1.0版本

img

2.創建一個類 SignalRHub.cs 用來自定義集線器 繼承自SignalR的集線器 代碼如下

using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
namespace SignalR_Server{	
    public class SignalRHub:Hub	{		
        public  async Task sendall(string user, string message)		
        {			
            await Clients.All.SendAsync("toall",user,message,"給所有人發");					
        }		
        /// <summary>		
        /// 重寫集線器連接事件		
        /// </summary>		
        /// <returns></returns>		
        public override Task OnConnectedAsync()		
        {			
            Console.WriteLine($"{Context.ConnectionId}已連接");			
            return base.OnConnectedAsync();		
        }		
        /// <summary>		
        /// 重寫集線器關閉事件		
        /// </summary>		
        /// <param name="exception"></param>		
        /// <returns></returns>		
        public override Task OnDisconnectedAsync(Exception exception)		
        {			
            Console.WriteLine("觸發了關閉事件");			
            return base.OnDisconnectedAsync(exception);		
        }	
    }}

3.修改Startup中的ConfigureServices方法 代碼如下

public void ConfigureServices(IServiceCollection services)		
{			
    //配置SignalR服務 配置跨域
    services.AddCors(options => options.AddPolicy("CorsPolicy",			   
                                                  builder =>			   
                                                  {				   
                                                      builder.AllowAnyMethod()						  
                                                          .AllowAnyHeader()						  
                                                          .WithOrigins("http://localhost:51083")						  
                                                          .AllowCredentials();			   
                                                  }));			
    services.AddSignalR();			
    services.AddControllers();		}

4.修改Startup中的Configure方法 代碼如下

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)		
{			
    if (env.IsDevelopment())
    {				
        app.UseDeveloperExceptionPage();
    }			
    app.UseRouting();
    //使用跨域			
    app.UseCors("CorsPolicy");
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
                     {
                         endpoints.MapControllers();
                         //使用集線器
                         endpoints.MapHub<SignalRHub>("/chatHub");
                     });
}

5.因為要實現前后端分離 這里我們再打開一個vs 創建一個mvc項目 用來模擬前端

img

將圖片上的這三個文件里面的代碼替換成我的 其中signalr.js是官方的 下載方式如下

(1)在“解決方案資源管理器” 中,右鍵單擊項目,然后選擇“添加” >“客戶端庫” 。
(2)在“添加客戶端庫” 對話框中,對於“提供程序” ,選擇“unpkg” 。
(3)對於“庫” ,輸入 @microsoft/signalr@3,然后選擇不是預覽版的最新版本
(4)選擇“選擇特定文件” ,展開“dist/browser” 文件夾,然后選擇“signalr.js” 和“signalr.min.js”
(5)將“目標位置” 設置為 wwwroot/js/ ,然后選擇“安裝”

該方法復制於弱水三千 只取一瓢飲

感謝老哥 大家也可以參考官方文檔進行下載

剩下的兩個文件代碼很簡單 我就不多說了

chat.js

"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:5000/chatHub").build();
//Disable send button until connection is establisheddocument.getElementById("sendButton").disabled = true;
//這個可以不一致
connection.on("toall", function (user, message,test) 
  {    
    var msg = message;
    var encodedMsg = user + " says " + msg + "\n來源是" + test;
    var li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);});connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;}).catch(function (err) {
    return console.error(err.toString());});document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;    
    var message = document.getElementById("messageInput").value;    
    //和服務器必須一致    
    connection.invoke("sendall", user, message).catch(function (err) {        
        return console.error(err.toString());    
    });    
    event.preventDefault();
});

Index.cshtml

@page<div class="container">    
    <div class="row"> </div>    
    <div class="row">        
        <div class="col-2">用戶名</div>        
        <div class="col-4"><input type="text" id="userInput" /></div>    
    </div>    
    <div class="row">        
        <div class="col-2">要發送的消息</div>        
    <div class="col-4"><input type="text" id="messageInput" /></div>    
    </div>    
    <div class="row"> 
    </div>    
    <div class="row">        
    <div class="col-6">            
        <input type="button" id="sendButton" value="發送消息" />        
        </div>    
    </div>
</div>
<div class="row">    
    <div class="col-12">        
        <hr />    
    </div>
</div>
<div class="row">    
    <div class="col-6">        
        <ul id="messagesList"></ul>    
    </div>
</div>
<script src="~/js/signalr.js"></script><script src="~/js/chat.js"></script>

然后啟動服務端和客戶端 注意這里服務端我們使用kestrel的方式啟動

img

啟動成功可以看到控制台成功打印出了連接的用戶id 測試發消息也正常

img

6.現在我們要通過api的方式進行請求了 在服務端新建一個控制器SignalRTestController 代碼如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Ladder.Data;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
namespace SignalR_Server.Controllers{
    [Route("api/[controller]")]	
    [ApiController]	
    public class SignalRTestController : ControllerBase	{		
        private readonly IHubContext<SignalRHub> _hubContext;		
        public SignalRTestController(IHubContext<SignalRHub> hubClients)		
        {			
            _hubContext = hubClients;		
        }		
        [HttpGet("index")]		
        public string index()		
        {			
            return "HELLO World";		
        }		
        [HttpGet("sendall")]		
        public void SendAll()		
        {			
            //給所有人推送消息			
            _hubContext.Clients.All.SendAsync("toall", "后端","你好","給所有人發");		
        }		
        [HttpGet("sendToUser")]		
        public void SendToUser(string user)		
        {			
            //給指定人推送消息			
            _hubContext.Clients.Client(user).SendAsync("toall", "后端", $"你好{user}", "只給你發");		
        }	
    }}

然后啟動服務端和客戶端 將客戶端的頁面打開兩個

測試一下給指定人發

img

測試一個給所有人發

img

ok啦~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM