本章將和大家分享使用 SignalR 生成實時應用的基礎知識。通過本文您將學習如何:使用ASP.NET Core SignalR + MVC + Vue 2.x + require 最終創建一個正常運行的簡易聊天應用。 ...
本章將和大家分享使用 SignalR 生成實時應用的基礎知識。通過本文您將學習如何:使用ASP.NET Core SignalR + MVC + Vue 2.x + require 最終創建一個正常運行的簡易聊天應用。
廢話不多說,我們直接來看一個Demo,Demo的目錄結構如下所示:
本Demo的Web項目為ASP.NET Core Web 應用程式(目標框架為.NET 7.0) MVC項目。
1、創建 SignalR 中心
中心是一個類,用作處理客戶端 - 伺服器通信的高級管道。
可通過已連接客戶端調用 SendMessage,以向所有客戶端發送消息。
using Microsoft.AspNetCore.SignalR; namespace SignalRChat.Hubs { /// <summary> /// Hub 類管理連接、組和消息 /// </summary> public class ChatHub : Hub { /// <summary> /// 可通過已連接客戶端調用 SendMessage,以向所有客戶端發送消息 /// </summary> public async Task SendMessage(string user, string message) { //Clients.All 向所有的客戶端發送消息(服務端調用客戶端) //ReceiveMessage 是客戶端監聽的方法 await Clients.All.SendAsync("ReceiveMessage", user, message); /* // 常用方法 // 給所有人發送消息 await Clients.All.SendAsync("ReceiveMessage", data); // 給組裡所有人發消息 await Clients.Group("Users").SendAsync("ReceiveMessage", data); // 給調用方法的那個人發消息 await Clients.Caller.SendAsync("ReceiveMessage", data); // 給除了調用方法的以外所有人發消息 await Clients.Others.SendAsync("ReceiveMessage", data); // 給指定connectionId的人發消息 await Clients.User(connectionId).SendAsync("ReceiveMessage", data); // 給指定connectionId的人發消息 await Clients.Client(connectionId).SendAsync("ReceiveMessage", data); // 給指定connectionId的人發消息,同時指定多個connectionId await Clients.Clients(IReadOnlyList<> connectionIds).SendAsync("ReceiveMessage", data); */ } } }
2、配置 SignalR
必須將 SignalR 伺服器配置為將 SignalR 請求傳遞給 SignalR。 將以下突出顯示(標紅)的代碼添加到 Program.cs 文件。
using SignalRChat.Hubs; namespace SignalRChat { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); //服務註冊(往容器中添加服務) // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddSignalR(); //SignalR var app = builder.Build(); //配置Http請求處理管道 // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); //配置MVC路由 app.MapControllerRoute( name: "areas", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapHub<ChatHub>("/chatHub"); //SignalR app.Run(); } } }
以上突出顯示(標紅)的代碼將 SignalR 添加到 ASP.NET Core 依賴關係註入和路由系統。
3、添加 SignalR 客戶端代碼
chat.js 文件,核心 JavaScript 代碼如下:
//第一個參數:載入依賴模塊,可以是require_config中定義的短模塊名,也可以是完整的模塊路徑(去掉.js尾碼名,根目錄為require_config中設置的baseUrl) //第二個參數:執行載入完後的回調函數 require(['../common/base', 'jquery', 'signalr'], function (base, $, signalR) { let axios = base.axios; var vm = new base.vue({ el: '#app', //掛載點 mixins: [base.mixin], //混入,類似基類的概念 data: { connectionSignalR: '', //SignalR連接 user: '', message: '', msgList: [] }, //created鉤子函數 created: function () { this.initSignalR(); //初始化SignalR }, //mounted鉤子函數 mounted: function () { //console.log('This is index mounted'); }, //方法 methods: { //初始化SignalR initSignalR: function () { var _this = this; //創建連接 _this.connectionSignalR = new signalR.HubConnectionBuilder() .withUrl("/chatHub") .configureLogging(signalR.LogLevel.Error) .build(); /* 日誌等級: signalR.LogLevel.Error:錯誤消息。 Error僅記錄消息。 signalR.LogLevel.Warning:有關潛在錯誤的警告消息。 日誌 Warning 和 Error 消息。 signalR.LogLevel.Information:無錯誤的狀態消息。 日誌 Information 、 Warning 和 Error 消息。 signalR.LogLevel.Trace:跟蹤消息。 記錄所有內容,包括中心和客戶端之間傳輸的數據。 */ //監聽中心(服務端)發送的消息(服務端調用客戶端) //ReceiveMessage 是服務端調用客戶端的方法名 _this.connectionSignalR.on("ReceiveMessage", function (user, message) { _this.msgList.push({ user: user, message: message }); }); //啟動連接 _this.connectionSignalR.start().then(function () { //啟動連接後需要立即執行的邏輯 //document.getElementById("sendButton").disabled = false; }).catch(function (err) { return console.error(err.toString()); }); }, //發送消息 sendMsg: function () { var _this = this; if (_this.message) { //向中心(服務端)發送消息(客戶端調用服務端) //SendMessage 是服務端定義的的方法 _this.connectionSignalR.invoke("SendMessage", _this.user, _this.message).catch(function (err) { return console.error(err.toString()); }); _this.message = ''; //發送完清空消息 } }, } }); });
公共腳本文件代碼如下:
其中 require_config.js 文件代碼如下:
//主要用來配置模塊的載入位置(設置短模塊名) require.config({ baseUrl: '/js/lib', //設置根目錄 paths: { //如果沒有設置根目錄則需要填寫完整路徑 'vue': 'vue', 'axios': 'axios', 'jquery': 'jquery-3.6.3', 'signalr': 'signalr', //paths還有一個重要的功能,就是可以配置多個路徑,如果遠程cdn庫沒有載入成功,可以載入本地的庫,如下: //'jquery': ['http://libs.baidu.com/jquery/2.0.3/jquery', '/js/lib/jquery-3.6.3'], } });
其中 base.js 文件代碼如下:
//define用來自定義模塊 //第一個參數:載入依賴模塊,可以是require_config中定義的短模塊名,也可以是完整的模塊路徑(去掉.js尾碼名) //第二個參數:執行載入完後的回調函數 define(['vue', 'axios', '../components/buttonCounter'], function (vue, axios, buttonCounter) { //TODO 此處可以處理一些公共的邏輯 //vue.component('component-a', { /* ... */ }); //全局註冊組件 //vue.mixin({...}); //全局混入 /* 定義組件名的方式有兩種: 1、使用 kebab-case (短橫線分隔命名) 當使用 kebab-case (短橫線分隔命名) 定義一個組件時,你也必須在引用這個自定義元素時使用 kebab-case,例如 <my-component-name> 2、使用 PascalCase (首字母大寫命名) 當使用 PascalCase (首字母大寫命名) 定義一個組件時,你在引用這個自定義元素時兩種命名法都可以使用。 也就是說 <my-component-name> 和 <MyComponentName> 都是可接受的。 註意,儘管如此,直接在 DOM (即非字元串的模板) 中使用時只有 kebab-case 是有效的。 */ //Vue.component(...) 的第一個參數為組件名。 vue.component('button-counter', buttonCounter); //全局註冊 return { vue: vue, axios: axios, //Vue混入 mixin: { //數據 data: function () { return { domain: '', //功能變數名稱 } }, //組件 components: { }, //created鉤子函數 created: function () { //console.log('This is base created'); var _this = this; _this.getDomain(); }, //mounted鉤子函數 mounted: function () { console.log('This is base mounted'); }, //方法 methods: { //測試 doTest: function () { console.log('This is base doTest'); }, //獲取功能變數名稱 getDomain: function () { var _this = this; _this.domain = 'http://localhost:5296'; }, } }, }; });
控制器和視圖文件代碼如下:
其中 HomeController 控制器代碼如下:
using Microsoft.AspNetCore.Mvc; using SignalRChat.Models; using System.Diagnostics; namespace SignalRChat.Controllers { public class HomeController : Controller { private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger) { _logger = logger; } public IActionResult Index() { return View(); } } }
其中佈局頁 _Layout.cshtml 視圖文件代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - SignalRChat</title> <script src="/js/lib/require.js"></script> <script src="/js/common/require_config.js"></script> @await RenderSectionAsync("header", required: false) </head> <body> <div class="container"> @RenderBody() </div> @await RenderSectionAsync("footer", required: false) </body> </html>
其中 Index.cshtml 視圖文件代碼如下:
@{ ViewData["Title"] = "Home Page"; } <div id="app"> <template> <p> User:<input v-model="user" type="text" /> </p> <p> Message: <input v-model="message" type="text" /> </p> <p> <button v-on:click="sendMsg">發送</button> </p> <hr /> <ul> <li v-for="(item, index) in msgList" :key="index"> {{ item.user }} says {{ item.message }} </li> </ul> </template> </div> @section footer{ <script src="/js/pageScript/chat.js"></script> }
4、運行應用
此處我使用的是 .NET Core CLI 命令行的方式來運行應用,如下所示:
打開兩個瀏覽器實例,分別訪問:http://localhost:5296/ , 運行結果如下:
選擇任一瀏覽器,輸入名稱和消息,然後點擊“發送”按鈕:
可以發現,兩個頁面上會立即顯示名稱和消息。
更多關於 ASP.NET Core SignalR 的相關知識可參考微軟官方文檔:https://learn.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-7.0&tabs=visual-studio
至此本文就全部介紹完了,如果覺得對您有所啟發請記得點個贊哦!!!
Demo源碼:
鏈接:https://pan.baidu.com/s/13ppUjr0h2dse5vnw5uiZ9Q 提取碼:qm2a
此文由博主精心撰寫轉載請保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/17520659.html
版權聲明:如有雷同純屬巧合,如有侵權請及時聯繫本人修改,謝謝!!!