日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 默认站点!

默认站点

當前位置: 首頁 >

如何在ASP.NET Core中使用SignalR构建与Angular通信的实时通信应用程序

發布時間:2023/12/4 29 豆豆
默认站点 收集整理的這篇文章主要介紹了 如何在ASP.NET Core中使用SignalR构建与Angular通信的实时通信应用程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

圖片

假設我們要創建一個監視Web應用程序,該應用程序為用戶提供了一個能夠顯示一系列信息的儀表板,這些信息會隨著時間的推移而更新。

第一種方法是在定義的時間間隔(輪詢)定期調用API 以更新儀表板上的數據。

無論如何,還是有一個問題:如果沒有更新的數據,我們會因請求而不必要地增加網絡流量。

一種替代方法是長輪詢技術:如果服務器沒有可用數據,則它可以使請求保持活動狀態,直到發生某種情況或達到預設的超時時間為止,而不是發送空響應。如果存在新數據,則完整的響應將到達客戶端。完全不同的方法是反轉角色:當有新數據可用(推送)時,后端與客戶端聯系。

請記住,HTML 5具有標準化的WebSocket,這是一個永久的雙向連接,可以在兼容的瀏覽器中使用Javascript接口進行配置。不幸的是,必須在客戶端和服務器端都對WebSocket提供完全支持,以使其可用。然后,我們需要提供替代系統(fallback),無論如何,該替代系統都允許我們的應用程序運行。

微軟于2013年發布了一個名為SignalR?for?ASP.NET的開源庫,該庫已于?2018年為ASP.NET Core進行了重寫。SignalR從與通信機制有關的所有細節中進行抽象,并從可用的信息中選擇最佳的一種。

結果是有可能編寫代碼,就像我們一直處于push-mode一樣。使用SignalR,服務器可以在其所有連接的客戶端或特定客戶端上調用JavaScript方法。

我們使用web-api模板創建一個ASP.NET Core項目,刪除已生成的示例控制器。使用NuGet,我們將Microsoft.AspNet.SignalR添加到項目中,以創建Hub

集線器是能夠調用客戶端代碼,發送包含所請求方法的名稱和參數的消息的高級管道。作為參數發送的對象將使用適當的協議反序列化。客戶端在頁面代碼中搜索與名稱相對應的方法,如果找到該名稱,則將其調用并傳遞反序列化的數據作為參數。

using Microsoft.AspNetCore.SignalR;namespace SignalR.Hubs {public class NotificationHub : Hub { } }

您可能知道,在ASP.NET Core中,可以配置HTTP請求的管理管道,以添加一些中間件,該中間件可攔截請求,添加已配置的功能并使其進入下一個中間件。必須預先配置SignalR中間件,在Startup?類的ConfigureServices

方法中添加擴展方法services.AddSignalR()。現在,我們可以使用Startup類的

Configure方法中的擴展方法app.UseSignalR()將中間件添加到管道中。

在此操作期間,我們可以傳遞配置參數,包括集線器的路由:

app.UseSignalR(route => {route.MapHub<notificationhub>("/notificationHub"); })

一個有趣的場景允許我們查看ASP.NET Core中的另一個有趣功能,即在后臺工作進程上下文中托管SignalR Hub 。 假設我們要實現以下用例:

?運行業務邏輯

?等一下?決定是停止還是重復該過程。

在ASP.NET Core中,我們可以使用框架提供的IHostedService接口在.NET Core應用程序中在后臺實現進程的執行。方法要實現是StartAsync()和StopAsync() 。非常簡單:StartAsync調用到主機啟動,而StopAsync調用到主機關閉。

然后,我們將一個類DashboardHostedService添加到項目中,該類實現

IHostedService。我們在Startup類的ConfigureServices方法中添加接口注冊:

services.AddHostedService<dashboardhostedservice>();

在類構造函數DashboardHostedService中,我們注入IHubContext

訪問添加到我們應用程序的集線器。在方法StartAsync中,我們設置了一個計時器,它將每兩秒鐘運行一次方法DoWork()中包含的代碼。此方法發送帶有四個隨意生成的字符串的消息。

但是它向誰傳播呢?在我們的示例中,我們正在將消息發送到所有連接的客戶端。但是,SignalR提供了向單個用戶或用戶組發送消息的機會。在本文中[1],您將找到涉及ASP.NET Core中的身份驗證和授權功能的詳細信息。

有趣的是,用戶可以同時在臺式機和移動設備上連接。每個設備都有一個單獨的SignalR連接,但是它們都將與同一用戶關聯。

using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Hosting; using SignalR.Hubs; using System; using System.Linq; using System.Threading; using System.Threading.Tasks;namespace SignalR {public class DashboardHostedService: IHostedService{private Timer _timer;private readonly IHubContext<notificationhub> _hubContext;public DashboardHostedService(IHubContext<notificationhub> hubContext){_hubContext = hubContext;}public Task StartAsync(CancellationToken cancellationToken){_timer = new Timer(DoWork, null, TimeSpan.Zero,TimeSpan.FromSeconds(2));return Task.CompletedTask;}private void DoWork(object state){_hubContext.Clients.All.SendAsync("SendMessage", new {val1 = getRandomString(),val2 = getRandomString(),val3 = getRandomString(),val4 = getRandomString()});}public Task StopAsync(CancellationToken cancellationToken){_timer?.Change(Timeout.Infinite, 0);return Task.CompletedTask;}} }

讓我們看看如何管理客戶端部分。例如,我們使用Angular CLI的ng new SignalR命令創建Angular應用程序。

然后我們安裝SignalR的包節點(

npm i @ aspnet / signalr

)。然后添加一個服務,該服務使我們可以連接到先前創建的集線器并接收消息。在這里,第一種可能的方法是,基于服務getMessage()中Observable 的服務,通過使用私有聲明的Subject?來返回(Message是與從Object返回的對象相對應的Typescript接口。后端):

@Injectable({providedIn: 'root' }) export class SignalRService {private message$: Subject<message>;private connection: signalR.HubConnection;constructor() {this.message$ = new Subject<message>();this.connection = new signalR.HubConnectionBuilder().withUrl(environment.hubUrl).build();this.connect();}private connect() {this.connection.start().catch(err => console.log(err));this.connection.on('SendMessage', (message) => {this.message$.next(message);});}public getMessage(): Observable<message> {return this.message$.asObservable();}public disconnect() {this.connection.stop();} }

在constructor()內部,我們創建一個SignalR.HubConnection類型對象,該對象將用于連接到服務器。我們通過使用文件environment.ts將其傳遞到其中心URL:

this.connection = new signalR.HubConnectionBuilder().withUrl(environment.hubUrl).build();

構造函數還負責調用connect()方法,該方法進行實際連接,并在控制臺中記錄可能的錯誤。

this.connection.start().catch(err => console.log(err)); this.connection.on('SendMessage', (message) => {this.message$.next(message); });

想要顯示來自后端的消息的組件(將其注入到構造函數中的服務),應該訂閱getMessage()方法并管理到達的消息。以AppComponent為例,例如:

@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css'] }) export class AppComponent implements OnDestroy {private signalRSubscription: Subscription;public content: Message;constructor(private signalrService: SignalRService) {this.signalRSubscription = this.signalrService.getMessage().subscribe((message) => {this.content = message;});}ngOnDestroy(): void {this.signalrService.disconnect();this.signalRSubscription.unsubscribe();} }

使用主題允許我們同時管理更多組件,而無論從中心返回的消息(用于訂閱還是用于取消訂閱)都可以,但是我們必須注意對主題的粗心使用。讓我們考慮以下getMessage()版本:

public getMessage(): Observable<message> {return this.message$; }

現在,該組件也可以使用以下簡單代碼發送一條消息:

const produceMessage = this.signalrService.getMessage() as Subject<any>;produceMessage.next( {val1: 'a'}); </any>

如果方法getMessage()返回SubjectasObservable,則此代碼將引發異常!我們可以在單個組件的情況下使用的第二種方法(更簡單)對管理來自后端的消息感興趣:

@Injectable({providedIn: 'root' }) export class SignalrService {connection: signalR.HubConnection;constructor() {this.connection = new signalR.HubConnectionBuilder().withUrl(environment.hubAddress).build();this.connect();}public connect() {if (this.connection.state === signalR.HubConnectionState.Disconnected) {this.connection.start().catch(err => console.log(err));}}public getMessage(next) {this.connection.on('SendMessage', (message) => {next(message);});}public disconnect() {this.connection.stop();} }

我們可以簡單地將函數回調傳遞給方法getMessage,該函數將來自后端的消息作為參數。在這種情況下,AppComponent可以成為:

public content: IMessage; constructor(private signalrService: SignalrService) {this.signalrService.getMessage((message: IMessage) => {this.content = message;}); } ngOnDestroy(): void {this.signalrService.disconnect(); }

最后幾行代碼分別位于app.component.html和app.component.css中

,以賦予一些時尚,并且該應用程序已完成。

<div style="text-align:center"><h1>DASHBOARD</h1> </div> <div class="card-container"><div class="card"><div class="container"><h4><b>Valore 1</b></h4><p>{{content.val1}}</p></div></div><div class="card"><div class="container"><h4><b>Valore 2</b></h4><p>{{content.val2}}</p></div></div><div class="card"><div class="container"><h4><b>Valore 3</b></h4><p>{{content.val3}}</p></div></div><div class="card"><div class="container"><h4><b>Valore 4</b></h4><p>{{content.val4}}</p></div></div> </div>.card-container {display: flex;flex-wrap: wrap; }.card {box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);transition: 0.3s;width: 40%;flex-grow: 1;margin: 10px; }.card:hover {box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); }.container {padding: 2px 16px; }

我們首先啟動后端,然后啟動前端并檢查最終結果:

看起來不錯!您可以在這里找到代碼:https[2]?:?//github.com/AARNOLD87/SignalRWithAngular[3]

下次見!

References

[1]?本文中:?https://docs.microsoft.com/en-us/aspnet/core/signalr/groups?view=aspnetcore-2.2
[2]?https:?https://github.com/AARNOLD87/SignalRWithAngular
[3]?//github.com/AARNOLD87/SignalRWithAngular:?https://github.com/AARNOLD87/SignalRWithAngular

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是默认站点為你收集整理的如何在ASP.NET Core中使用SignalR构建与Angular通信的实时通信应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得默认站点網站內容還不錯,歡迎將默认站点推薦給好友。