国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ASP.NET Core SignalR 系列(二)- 中心(服務(wù)端)

這篇具有很好參考價(jià)值的文章主要介紹了ASP.NET Core SignalR 系列(二)- 中心(服務(wù)端)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

本章將和大家分享 ASP.NET Core SignalR 中的中心(服務(wù)端)。

本文大部分內(nèi)容摘自微軟官網(wǎng):https://learn.microsoft.com/zh-cn/aspnet/core/signalr/hubs?view=aspnetcore-7.0

廢話不多說(shuō),我們直接來(lái)看一個(gè)Demo,Demo的目錄結(jié)構(gòu)如下所示:

ASP.NET Core SignalR 系列(二)- 中心(服務(wù)端)

本Demo的Web項(xiàng)目為ASP.NET Core Web 應(yīng)用程序(目標(biāo)框架為.NET 7.0) MVC項(xiàng)目。

1、創(chuàng)建和使用中心

通過(guò)聲明繼承自 Hub 的類來(lái)創(chuàng)建中心。將方法添加到 public 類,使其可從客戶端調(diào)用:

using Microsoft.AspNetCore.SignalR;

namespace SignalRChat.Hubs
{
    /// <summary>
    /// Hub 類管理連接、組和消息
    /// </summary>
    public class ChatHub : Hub
    {
        /// <summary>
        /// 可通過(guò)已連接客戶端調(diào)用 SendMessage,以向所有客戶端發(fā)送消息
        /// </summary>
        public async Task SendMessage(string user, string message)
        {
            //Clients.All 向所有的客戶端發(fā)送消息(服務(wù)端調(diào)用客戶端)
            //ReceiveMessage 是客戶端監(jiān)聽(tīng)的方法
            await Clients.All.SendAsync("ReceiveMessage", user, message);

            /*
                // 常用方法
                // 給所有人發(fā)送消息
                await Clients.All.SendAsync("ReceiveMessage", data);

                // 給組里所有人發(fā)消息
                await Clients.Group("Users").SendAsync("ReceiveMessage", data);

                // 給調(diào)用方法的那個(gè)人發(fā)消息
                await Clients.Caller.SendAsync("ReceiveMessage", data);

                // 給除了調(diào)用方法的以外所有人發(fā)消息
                await Clients.Others.SendAsync("ReceiveMessage", data);

                // 給指定connectionId的人發(fā)消息
                await Clients.User(connectionId).SendAsync("ReceiveMessage", data);

                // 給指定connectionId的人發(fā)消息
                await Clients.Client(connectionId).SendAsync("ReceiveMessage", data);

                // 給指定connectionId的人發(fā)消息,同時(shí)指定多個(gè)connectionId
                await Clients.Clients(IReadOnlyList<> connectionIds).SendAsync("ReceiveMessage", data);
            */
        }
    }
}

中心是暫時(shí)性的:

不要將狀態(tài)存儲(chǔ)在中心類的屬性中。每個(gè)中心方法調(diào)用都在新的中心實(shí)例上執(zhí)行。

請(qǐng)勿通過(guò)依賴項(xiàng)注入直接實(shí)例化中心。若要從應(yīng)用程序中的其他位置向客戶端發(fā)送消息,請(qǐng)使用 IHubContext 。

調(diào)用依賴于保持活動(dòng)狀態(tài)的中心的異步方法時(shí)請(qǐng)使用 await。例如,如果在沒(méi)有 await 的情況下進(jìn)行調(diào)用,則 Clients.All.SendAsync(...) 這類方法會(huì)失敗,并且中心方法會(huì)在 SendAsync 完成之前完成。

2、配置 SignalR 中心?

注冊(cè)中心所需的 SignalR 服務(wù) 以及 配置SignalR終結(jié)點(diǎn),修改 Program.cs 文件的代碼,如下所示:

using SignalRChat.Hubs;

namespace SignalRChat
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            //服務(wù)注冊(cè)(往容器中添加服務(wù))
            // Add services to the container.
            builder.Services.AddControllersWithViews();
            builder.Services.AddSignalR(); //注冊(cè)中心所需的 SignalR 服務(wù)

            var app = builder.Build();

            //配置Http請(qǐng)求處理管道
            // 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?}");

            //配置SignalR終結(jié)點(diǎn)
            app.MapHub<ChatHub>("/chatHub"); //中心
            app.MapHub<StronglyTypedChatHub>("/stronglyTypedChatHub"); //強(qiáng)類型中心

            app.Run();
        }
    }
}

3、上下文對(duì)象

類 Hub 包含一個(gè) Context 屬性,該屬性包含以下屬性以及有關(guān)連接的信息:

屬性 說(shuō)明
ConnectionId 獲取連接的唯一 ID(由 SignalR 分配)。每個(gè)連接都有一個(gè)連接 ID。
UserIdentifier 獲取用戶標(biāo)識(shí)符。 默認(rèn)情況下,SignalR 使用與連接關(guān)聯(lián)的 ClaimsPrincipal 中的 ClaimTypes.NameIdentifier 作為用戶標(biāo)識(shí)符。
User 獲取與當(dāng)前用戶關(guān)聯(lián)的 ClaimsPrincipal。
Items 獲取可用于在此連接范圍內(nèi)共享數(shù)據(jù)的鍵/值集合。數(shù)據(jù)可以存儲(chǔ)在此集合中,會(huì)在不同的中心方法調(diào)用間為連接持久保存。
Features 獲取連接上可用的功能的集合。目前,在大多數(shù)情況下不需要此集合,因此未對(duì)其進(jìn)行詳細(xì)記錄。
ConnectionAborted 獲取一個(gè) CancellationToken,它會(huì)在連接中止時(shí)發(fā)出通知。

Hub.Context 還包含以下方法:

方法 說(shuō)明
GetHttpContext 獲取 Http 請(qǐng)求的上下文對(duì)象,如果不是 Http 請(qǐng)求,則返回 null 。
Abort 中止連接。

4、客戶端對(duì)象

類 Hub 包含一個(gè) Clients 屬性,該屬性包含以下屬性,用于服務(wù)器和客戶端之間的通信:

屬性 說(shuō)明
?All ?對(duì)所有連接的客戶端調(diào)用方法
?Caller ?對(duì)調(diào)用了中心方法的客戶端調(diào)用方法
?Others ?對(duì)所有連接的客戶端調(diào)用方法(調(diào)用了方法的客戶端除外)

Hub.Clients 還包含以下方法:

方法 說(shuō)明
AllExcept 對(duì)所有連接的客戶端調(diào)用方法(指定連接除外)
Client 對(duì)連接的一個(gè)特定客戶端調(diào)用方法
Clients 對(duì)連接的多個(gè)特定客戶端調(diào)用方法
Group 對(duì)指定組中的所有連接調(diào)用方法
GroupExcept 對(duì)指定組中的所有連接調(diào)用方法(指定連接除外)
Groups 對(duì)多個(gè)連接組調(diào)用方法
OthersInGroup 對(duì)一個(gè)連接組調(diào)用方法(不包括調(diào)用了中心方法的客戶端)
User 對(duì)與一個(gè)特定用戶關(guān)聯(lián)的所有連接調(diào)用方法
Users 對(duì)與多個(gè)指定用戶關(guān)聯(lián)的所有連接調(diào)用方法

以上表中的每個(gè)屬性或方法都返回具有 SendAsync 方法的對(duì)象。 方法 SendAsync 接收要調(diào)用的客戶端方法的名稱和任何參數(shù)。

5、向客戶端發(fā)送消息

若要對(duì)特定客戶端發(fā)出調(diào)用,請(qǐng)使用 Clients 對(duì)象的屬性。?在以下示例中,有三種中心方法:

using Microsoft.AspNetCore.SignalR;

namespace SignalRChat.Hubs
{
    /// <summary>
    /// Hub 類管理連接、組和消息
    /// </summary>
    public class ChatHub : Hub
    {
        /// <summary>
        /// 可通過(guò)已連接客戶端調(diào)用 SendMessage,以向所有客戶端發(fā)送消息
        /// </summary>
        public async Task SendMessage(string user, string message)
        {
            //Clients.All 向所有的客戶端發(fā)送消息(服務(wù)端調(diào)用客戶端)
            //ReceiveMessage 是客戶端監(jiān)聽(tīng)的方法
            await Clients.All.SendAsync("ReceiveMessage", user, message); //將消息發(fā)送到所有連接的客戶端

            /*
                // 常用方法
                // 給所有人發(fā)送消息
                await Clients.All.SendAsync("ReceiveMessage", data);

                // 給組里所有人發(fā)消息
                await Clients.Group("Users").SendAsync("ReceiveMessage", data);

                // 給調(diào)用方法的那個(gè)人發(fā)消息
                await Clients.Caller.SendAsync("ReceiveMessage", data);

                // 給除了調(diào)用方法的以外所有人發(fā)消息
                await Clients.Others.SendAsync("ReceiveMessage", data);

                // 給指定connectionId的人發(fā)消息
                await Clients.User(connectionId).SendAsync("ReceiveMessage", data);

                // 給指定connectionId的人發(fā)消息
                await Clients.Client(connectionId).SendAsync("ReceiveMessage", data);

                // 給指定connectionId的人發(fā)消息,同時(shí)指定多個(gè)connectionId
                await Clients.Clients(IReadOnlyList<> connectionIds).SendAsync("ReceiveMessage", data);
            */
        }

        public async Task SendMessageToCaller(string user, string message)
            => await Clients.Caller.SendAsync("ReceiveMessage", user, message); //將消息發(fā)送回調(diào)用方

        public async Task SendMessageToGroup(string user, string message)
            => await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message); //將消息發(fā)送給 SignalR Users 組中的所有客戶端
    }
}

6、強(qiáng)類型中心

使用 SendAsync 的缺點(diǎn)是它依賴于字符串來(lái)指定要調(diào)用的客戶端方法。 如果客戶端中的方法名稱拼寫(xiě)錯(cuò)誤或缺失,則這會(huì)使代碼可能出現(xiàn)運(yùn)行時(shí)錯(cuò)誤。

使用 SendAsync 的另一種方法是使用 Hub<T>強(qiáng)類型Hub類。 在以下示例中 ChatHub ,客戶端方法已提取到名為 的 IChatClient接口中:

namespace SignalRChat.Hubs
{
    public interface IChatClient
    {
        /// <summary>
        /// 客戶端方法
        /// </summary>
        Task ReceiveMessage(string user, string message);
    }
}

此接口可用于將前面的 ChatHub 示例重構(gòu)為強(qiáng)類型:

using Microsoft.AspNetCore.SignalR;

namespace SignalRChat.Hubs
{
    /// <summary>
    /// 強(qiáng)類型中心
    /// 中心是暫時(shí)性的:不要將狀態(tài)存儲(chǔ)在中心類的屬性中。每個(gè)中心方法調(diào)用都在新的中心實(shí)例上執(zhí)行。
    /// </summary>
    public class StronglyTypedChatHub : Hub<IChatClient>
    {
        [HubMethodName("SendMessage")] //更改中心方法的名稱
        public async Task SendMessage(string user, string message)
            => await Clients.All.ReceiveMessage(user, message); //將消息發(fā)送到所有連接的客戶端

        public async Task SendMessageToCaller(string user, string message)
            => await Clients.Caller.ReceiveMessage(user, message); //將消息發(fā)送回調(diào)用方

        public async Task SendMessageToGroup(string user, string message)
            => await Clients.Group("SignalR Users").ReceiveMessage(user, message); //將消息發(fā)送給 SignalR Users 組中的所有客戶端
    }
}

使用 Hub<IChatClient> 可以對(duì)客戶端方法進(jìn)行編譯時(shí)檢查。 這可以防止使用字符串導(dǎo)致的問(wèn)題,因?yàn)?Hub<T> 只能提供對(duì) 接口中定義的方法的訪問(wèn)。 使用強(qiáng)類型 Hub<T> 會(huì)禁止使用 SendAsync。

備注:Async后綴不會(huì)從方法名稱中去除。 除非使用 .on('MyMethodAsync')定義客戶端方法,否則不要使用 MyMethodAsync 作為名稱。

7、更改中心方法的名稱

默認(rèn)情況下,服務(wù)器中心方法名稱是 .NET 方法的名稱。若要更改特定方法的此默認(rèn)行為,請(qǐng)使用 HubMethodName 特性。調(diào)用方法時(shí),客戶端應(yīng)使用此名稱而不是 .NET 方法名稱:

[HubMethodName("SendMessageToUser")]
public async Task DirectMessage(string user, string message)
    => await Clients.User(user).SendAsync("ReceiveMessage", user, message);

8、將服務(wù)注入中心

中心構(gòu)造函數(shù)可以接受 DI 中的服務(wù)作為參數(shù),這些參數(shù)可以存儲(chǔ)在類的屬性中,以便在中心方法中使用。

為不同的中心方法注入多個(gè)服務(wù)或作為編寫(xiě)代碼的替代方法時(shí),中心方法也可以接受 DI 中的服務(wù)。 默認(rèn)情況下,如果可能,將從 DI 檢查和解析中心方法參數(shù)。

services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();

// ...

public class ChatHub : Hub
{
    public Task SendMessage(string user, string message, IDatabaseService dbService)
    {
        var userName = dbService.GetUserName(user);
        return Clients.All.SendAsync("ReceiveMessage", userName, message);
    }
}

如果不需要從服務(wù)隱式解析參數(shù),請(qǐng)使用 DisableImplicitFromServicesParameters 禁用它。 若要在中心方法中顯式指定從 DI 解析的參數(shù),請(qǐng)使用 DisableImplicitFromServicesParameters 選項(xiàng),并使用 [FromServices] 屬性或自定義屬性,該屬性在應(yīng)從 DI 解析的中心方法參數(shù)上實(shí)現(xiàn) IFromServiceMetadata 。

services.AddSingleton<IDatabaseService, DatabaseServiceImpl>();
services.AddSignalR(options =>
{
    options.DisableImplicitFromServicesParameters = true;
});

// ...

public class ChatHub : Hub
{
    public Task SendMessage(string user, string message,
        [FromServices] IDatabaseService dbService)
    {
        var userName = dbService.GetUserName(user);
        return Clients.All.SendAsync("ReceiveMessage", userName, message);
    }
}

9、為連接處理事件

SignalR 中心 API 提供 OnConnectedAsync 和 OnDisconnectedAsync 虛方法來(lái)管理和跟蹤連接。

/// <summary>
/// 在客戶端連接到中心時(shí)執(zhí)行操作
/// </summary>
/// <returns></returns>
public override async Task OnConnectedAsync()
{
    await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
    await base.OnConnectedAsync();
}

/// <summary>
/// 在客戶端斷開(kāi)連接時(shí)執(zhí)行操作
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public override async Task OnDisconnectedAsync(Exception? exception)
{
    await base.OnDisconnectedAsync(exception);
}

其中如果客戶端有意斷開(kāi)連接(例如通過(guò)調(diào)用 connection.stop()),則 exception 參數(shù)為 null。但是,如果客戶端由于錯(cuò)誤(例如網(wǎng)絡(luò)故障)而斷開(kāi)連接,則 exception 參數(shù)包含描述故障的異常。

RemoveFromGroupAsync 無(wú)需在 OnDisconnectedAsync 中調(diào)用,系統(tǒng)會(huì)自動(dòng)處理它。

10、從中心外部發(fā)送消息

SignalR 中心是用于向連接到 SignalR 服務(wù)器的客戶端發(fā)送消息的核心抽象。 你也可以使用 IHubContext 服務(wù)從應(yīng)用中的其他位置發(fā)送消息。

備注:IHubContext 用于將通知發(fā)送到客戶端,而非用于調(diào)用 Hub 上的方法。

1)獲取 IHubContext 實(shí)例

在 ASP.NET Core SignalR 中,你可以通過(guò)依賴項(xiàng)注入來(lái)訪問(wèn) IHubContext 實(shí)例。 你可以將 IHubContext 實(shí)例注入控制器、中間件或其他 DI 服務(wù)。 使用該實(shí)例向客戶端發(fā)送消息。

2)在控制器中注入 IHubContext 實(shí)例

通過(guò)將 IHubContext 實(shí)例添加到構(gòu)造函數(shù),可以將其注入控制器:

public class HomeController : Controller
{
    private readonly IHubContext<NotificationHub> _hubContext;

    public HomeController(IHubContext<NotificationHub> hubContext)
    {
        _hubContext = hubContext;
    }
}

獲權(quán)訪問(wèn) IHubContext 實(shí)例后,就像在中心本身一樣調(diào)用客戶端方法:

public async Task<IActionResult> Index()
{
    await _hubContext.Clients.All.SendAsync("Notify", $"Home page loaded at: {DateTime.Now}");
    return View();
}

3)在中間件中獲取 IHubContext 實(shí)例

訪問(wèn)中間件管道中的 IHubContext,如下所示:

app.Use(async (context, next) =>
{
    var hubContext = context.RequestServices
                            .GetRequiredService<IHubContext<ChatHub>>();
    //...
    
    if (next != null)
    {
        await next.Invoke();
    }
});

備注:當(dāng)從 Hub 類外部調(diào)用客戶端方法時(shí),沒(méi)有與該調(diào)用關(guān)聯(lián)的調(diào)用方。 因此,無(wú)法訪問(wèn) ConnectionId、Caller 和 Others 屬性。

4)從 IHost 獲取 IHubContext 實(shí)例

從 Web 主機(jī)訪問(wèn) IHubContext 對(duì)于與 ASP.NET Core 之外的區(qū)域集成很有用,例如,使用第三方依賴項(xiàng)注入框架:

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        var hubContext = host.Services.GetService(typeof(IHubContext<ChatHub>));
        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder => {
                webBuilder.UseStartup<Startup>();
            });
}

5)注入強(qiáng)類型 HubContext

若要注入強(qiáng)類型 HubContext,請(qǐng)確保中心繼承自 Hub<T>。 使用 IHubContext<THub, T> 接口而不是 IHubContext<THub> 進(jìn)行注入。

public class ChatController : Controller
{
    public IHubContext<ChatHub, IChatClient> _strongChatHubContext { get; }

    public ChatController(IHubContext<ChatHub, IChatClient> chatHubContext)
    {
        _strongChatHubContext = chatHubContext;
    }

    public async Task SendMessage(string user, string message)
    {
        await _strongChatHubContext.Clients.All.ReceiveMessage(user, message);
    }
}

6)在泛型代碼中使用 IHubContext

注入的 IHubContext<THub> 實(shí)例可以強(qiáng)制轉(zhuǎn)換為 IHubContext,而無(wú)需指定泛型 Hub 類型。

class MyHub : Hub
{ }

class MyOtherHub : Hub
{ }

app.Use(async (context, next) =>
{
    var myHubContext = context.RequestServices
                            .GetRequiredService<IHubContext<MyHub>>();
    var myOtherHubContext = context.RequestServices
                            .GetRequiredService<IHubContext<MyOtherHub>>();
    await CommonHubContextMethod((IHubContext)myHubContext);
    await CommonHubContextMethod((IHubContext)myOtherHubContext);

    await next.Invoke();
}

async Task CommonHubContextMethod(IHubContext context)
{
    await context.Clients.All.SendAsync("clientMethod", new Args());
}

此操作在以下情況下十分有用:

  • 編寫(xiě)不引用應(yīng)用正在使用的特定 Hub 類型的庫(kù)。
  • 編寫(xiě)可應(yīng)用于多個(gè)不同 Hub 實(shí)現(xiàn)的泛型代碼。

11、管理 SignalR 中的用戶和組

SignalR 允許將消息發(fā)送到與特定用戶關(guān)聯(lián)的所有連接,以及指定的連接組。

1)SignalR 中的用戶

SignalR 中的單個(gè)用戶可以與一個(gè)應(yīng)用建立多個(gè)連接。 例如,用戶可以在桌面和手機(jī)上進(jìn)行連接。 每臺(tái)設(shè)備都有一個(gè)單獨(dú)的 SignalR 連接,但它們都與同一個(gè)用戶關(guān)聯(lián)。 如果向用戶發(fā)送消息,則與該用戶關(guān)聯(lián)的所有連接都會(huì)收到消息。 可以通過(guò)中心內(nèi)的 Context.UserIdentifier 屬性訪問(wèn)連接的用戶標(biāo)識(shí)符。

默認(rèn)情況下,SignalR 使用與連接關(guān)聯(lián)的 ClaimsPrincipal 中的 ClaimTypes.NameIdentifier 作為用戶標(biāo)識(shí)符。 若要自定義此行為,請(qǐng)參閱使用聲明自定義標(biāo)識(shí)處理。

通過(guò)將用戶標(biāo)識(shí)符傳遞給中心方法中的 User 函數(shù),向特定用戶發(fā)送消息,如以下示例所示:

public Task SendPrivateMessage(string user, string message)
{
    return Clients.User(user).SendAsync("ReceiveMessage", message);
}

備注:用戶標(biāo)識(shí)符區(qū)分大小寫(xiě)。

2)SignalR 中的組

組是與名稱關(guān)聯(lián)的連接集合。你可以將消息發(fā)送到組中的所有連接。建議通過(guò)組發(fā)送到一個(gè)或多個(gè)連接,因?yàn)榻M由應(yīng)用程序管理。一個(gè)連接可以是多個(gè)組的成員。組非常適合聊天應(yīng)用程序之類的應(yīng)用,其中每個(gè)聊天室都可以表示為一個(gè)組。可通過(guò) AddToGroupAsync 和 RemoveFromGroupAsync 方法在組中添加或刪除連接。

public async Task AddToGroup(string groupName)
{
    await Groups.AddToGroupAsync(Context.ConnectionId, groupName);

    await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
}

public async Task RemoveFromGroup(string groupName)
{
    await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);

    await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
}

重新連接時(shí)不會(huì)保留組成員身份。重新建立連接后,需要重新加入組。無(wú)法計(jì)算組的成員數(shù),因?yàn)槿绻麑?yīng)用程序擴(kuò)展到多臺(tái)服務(wù)器,則無(wú)法獲取此信息。

若要在使用組時(shí)保護(hù)對(duì)資源的訪問(wèn),請(qǐng)使用 ASP.NET Core 中的身份驗(yàn)證和授權(quán)功能。如果僅當(dāng)憑據(jù)對(duì)組有效時(shí)才將用戶添加到該組,則發(fā)送到該組的消息將僅發(fā)送給授權(quán)用戶。但是,組不是一項(xiàng)安全功能。身份驗(yàn)證聲明具有組不具備的功能,例如到期和撤銷。如果撤銷用戶對(duì)組的訪問(wèn)權(quán)限,應(yīng)用必須從組中顯式刪除該用戶。

備注:組名稱區(qū)分大小寫(xiě)。

12、SignalR API 設(shè)計(jì)注意事項(xiàng)

使用自定義對(duì)象參數(shù)確保向后兼容性

將新的參數(shù)添加到 SignalR 客戶端或服務(wù)器上的中心方法是一項(xiàng)重大更改。這意味著,較舊的客戶端/服務(wù)器在嘗試調(diào)用沒(méi)有適當(dāng)數(shù)量參數(shù)的方法時(shí)會(huì)出錯(cuò)。但是,向自定義對(duì)象參數(shù)添加屬性不是一項(xiàng)中斷性變更。這可用于設(shè)計(jì)兼容的 API,以適應(yīng)客戶端或服務(wù)器上的更改。

使用自定義對(duì)象作為參數(shù)可提供更大的靈活性,如下所示:

public class TotalLengthRequest
{
    public string Param1 { get; set; }
    public string Param2 { get; set; }
}

public async Task GetTotalLength(TotalLengthRequest req)
{
    var length = req.Param1.Length;
    if (req.Param2 != null)
    {
        length += req.Param2.Length;
    }
    return length;
}

當(dāng)舊客戶端發(fā)送單個(gè)參數(shù)時(shí),額外的?Param2?屬性將保留為?null。 你可以通過(guò)檢查?Param2?是否為?null?來(lái)檢測(cè)舊客戶端發(fā)送的消息并應(yīng)用默認(rèn)值。 新客戶端可以發(fā)送這兩個(gè)參數(shù)。

connection.invoke("GetTotalLength", { param1: "value1", param2: "value2" });

此技術(shù)同樣適用于客戶端上定義的方法。 你可以從服務(wù)器端發(fā)送自定義對(duì)象:

public async Task Broadcast(string message)
{
    await Clients.All.SendAsync("ReceiveMessage", new
    {
        Sender = Context.User.Identity.Name,
        Message = message
    });
}

舊客戶端不需要?Sender?值,因此會(huì)忽略它。 新客戶端可以通過(guò)更新為讀取新屬性來(lái)接受它:

connection.on("ReceiveMessage", (req) => {
    let message = req.message;
    if (req.sender) {
        message = req.sender + ": " + message;
    }
    appendMessageToChatWindow(message);
});

在這種情況下,新客戶端也可以容忍不提供?Sender?值的舊服務(wù)器。由于舊服務(wù)器不提供?Sender?值,因此客戶端在訪問(wèn)它之前會(huì)檢查它是否存在。

?

Demo源碼:

鏈接:https://pan.baidu.com/s/1AbGaPRfv2vAskHRAnOlvYA 
提取碼:456q

此文由博主精心撰寫(xiě)轉(zhuǎn)載請(qǐng)保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/17536693.html

版權(quán)聲明:如有雷同純屬巧合,如有侵權(quán)請(qǐng)及時(shí)聯(lián)系本人修改,謝謝!??!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-533740.html

到了這里,關(guān)于ASP.NET Core SignalR 系列(二)- 中心(服務(wù)端)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 什么是 ASP.NET Core SignalR?

    所有連接了 Internet 的應(yīng)用程序都由服務(wù)器和客戶端組成。 客戶端依賴于服務(wù)器獲取數(shù)據(jù),而它們獲取數(shù)據(jù)的主要機(jī)制是通過(guò)發(fā)出超文本傳輸協(xié)議 (HTTP) 請(qǐng)求來(lái)進(jìn)行的。 某些客戶端應(yīng)用程序需要經(jīng)常更改的數(shù)據(jù)。 ASP.NET Core SignalR 提供了一個(gè) API,用于創(chuàng)建服務(wù)器到客戶端遠(yuǎn)程過(guò)

    2024年02月15日
    瀏覽(92)
  • 服務(wù)端使用ASP.NET Core SignalR與Vue3(TypeScript與JavaScript)前端建立通信(以進(jìn)度條為例)

    服務(wù)端使用ASP.NET Core SignalR與Vue3(TypeScript與JavaScript)前端建立通信(以進(jìn)度條為例)

    1. ASP.NET Core ? ? ? ? ? ASP.NET Core 是一個(gè)跨平臺(tái)、高性能及開(kāi)源的框架,用于生成基于云且連接互聯(lián)網(wǎng)的新式應(yīng)用程式。 官方文檔:ASP.NET documentation | Microsoft Learn ?2.? ASP.NET Core SignalR ? ? ? ? ASP.NET Core SignalR 是開(kāi)源庫(kù),用于服務(wù)端與客戶端建立實(shí)時(shí)通信,可以自動(dòng)管理連接

    2024年02月06日
    瀏覽(22)
  • ASP.NET Core實(shí)時(shí)庫(kù)SignalR簡(jiǎn)單應(yīng)用

    ASP.NET Core實(shí)時(shí)庫(kù)SignalR簡(jiǎn)單應(yīng)用

    SignalR 是用于構(gòu)建需要實(shí)時(shí)用戶交互或?qū)崟r(shí)數(shù)據(jù)更新的Web 應(yīng)用程序的一個(gè)開(kāi)放源代碼.NET 庫(kù)。不僅僅用在Web應(yīng)用中,后面會(huì)講到它的應(yīng)用范圍。它簡(jiǎn)化了簡(jiǎn)化了構(gòu)建實(shí)時(shí)應(yīng)用程序的過(guò)程,包括 ASP.NET Server 庫(kù)和 JavaScript Client 庫(kù),以便管理Client與Server連接并將內(nèi)容更新推送給Cl

    2024年02月11日
    瀏覽(23)
  • ASP.NET Core+Vue3 實(shí)現(xiàn)SignalR通訊

    ASP.NET Core+Vue3 實(shí)現(xiàn)SignalR通訊

    從ASP.NET Core 3.0版本開(kāi)始,SignalR的Hub已經(jīng)集成到了ASP.NET Core框架中。因此,在更高版本的ASP.NET Core中,不再需要單獨(dú)引用Microsoft.AspNetCore.SignalR包來(lái)使用Hub。 在項(xiàng)目創(chuàng)建一個(gè)類繼承Hub, 首先是寫(xiě)一個(gè)CreateConnection方法 ConnectionId是SignalR中標(biāo)識(shí)的客戶端連接的唯一標(biāo)識(shí)符, 將userId和

    2024年02月06日
    瀏覽(24)
  • Web SSH 的原理與在 ASP.NET Core SignalR 中的實(shí)現(xiàn)

    Web SSH 的原理與在 ASP.NET Core SignalR 中的實(shí)現(xiàn)

    有個(gè)項(xiàng)目,需要在前端有個(gè)管理終端可以 SSH 到主控機(jī)的終端,如果不考慮用戶使用 vim 等需要在控制臺(tái)內(nèi)現(xiàn)實(shí)界面的軟件的話,其實(shí)使用 Process 類型去啟動(dòng)相應(yīng)程序就夠了。而這次的需求則需要考慮用戶會(huì)做相關(guān)設(shè)置。 這里用到的原理是偽終端。偽終端(pseudo terminal)是現(xiàn)

    2024年02月07日
    瀏覽(20)
  • 微信小程序如何使用原生Websocket與Asp.Net Core SignalR 通信

    微信小程序如何使用原生Websocket與Asp.Net Core SignalR 通信

    如題,這可能算是.net 做小程序的服務(wù)端時(shí),繞不開(kāi)的一個(gè)問(wèn)題,老生常談了。同樣的問(wèn)題,我記得我2018/19年的一個(gè)項(xiàng)目的解決方案是: 修改官方的SignalR.js的客戶端 :把里面用到瀏覽器的Websocket改成微信小程序的官方api的。目前網(wǎng)上也有不少這樣的方案,已經(jīng)改好開(kāi)源了;

    2024年02月08日
    瀏覽(129)
  • 微信小程序如何使用原生Websocket api與Asp.Net Core SignalR 通信

    微信小程序如何使用原生Websocket api與Asp.Net Core SignalR 通信

    如題,這可能算是.net 做小程序的服務(wù)端時(shí),繞不開(kāi)的一個(gè)問(wèn)題,老生常談了。同樣的問(wèn)題,我記得我2018/19年的一個(gè)項(xiàng)目的解決方案是: 修改官方的SignalR.js的客戶端 :把里面用到瀏覽器的Websocket改成微信小程序的官方api的。目前網(wǎng)上也有不少這樣的方案,已經(jīng)改好開(kāi)源了;

    2024年02月09日
    瀏覽(39)
  • Asp .Net Core 系列:集成 Ocelot+Consul實(shí)現(xiàn)網(wǎng)關(guān)、服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)

    Asp .Net Core 系列:集成 Ocelot+Consul實(shí)現(xiàn)網(wǎng)關(guān)、服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)

    Ocelot是一個(gè)開(kāi)源的ASP.NET Core微服務(wù)網(wǎng)關(guān),它提供了API網(wǎng)關(guān)所需的所有功能,如路由、認(rèn)證、限流、監(jiān)控等。 Ocelot是一個(gè)簡(jiǎn)單、靈活且功能強(qiáng)大的API網(wǎng)關(guān),它可以與現(xiàn)有的服務(wù)集成,并幫助您保護(hù)、監(jiān)控和擴(kuò)展您的微服務(wù)。 以下是Ocelot的一些主要功能: 路由管理:Ocelot允許您

    2024年01月17日
    瀏覽(24)
  • Asp .Net Core 系列: 集成 Consul 實(shí)現(xiàn) 服務(wù)注冊(cè)與健康檢查

    Asp .Net Core 系列: 集成 Consul 實(shí)現(xiàn) 服務(wù)注冊(cè)與健康檢查

    官網(wǎng):https://www.consul.io/ Consul 是一款開(kāi)源的服務(wù)發(fā)現(xiàn)和配置管理工具,它能夠監(jiān)控應(yīng)用程序和服務(wù)之間的通信,并提供了一組 API 和 Web UI,用于管理服務(wù)和配置。 Consul 是分布式的、高可用的、可橫向擴(kuò)展的,具備以下特性: 服務(wù)發(fā)現(xiàn):Consul 通過(guò) DNS 或者 HTTP 接口使服務(wù)注冊(cè)

    2024年01月21日
    瀏覽(21)
  • Asp .Net Core 系列:集成 Ocelot+Nacos+Swagger+Cors實(shí)現(xiàn)網(wǎng)關(guān)、服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)

    Asp .Net Core 系列:集成 Ocelot+Nacos+Swagger+Cors實(shí)現(xiàn)網(wǎng)關(guān)、服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)

    什么是 Ocelot ? Ocelot是一個(gè)開(kāi)源的ASP.NET Core微服務(wù)網(wǎng)關(guān),它提供了API網(wǎng)關(guān)所需的所有功能,如路由、認(rèn)證、限流、監(jiān)控等。 Ocelot是一個(gè)簡(jiǎn)單、靈活且功能強(qiáng)大的API網(wǎng)關(guān),它可以與現(xiàn)有的服務(wù)集成,并幫助您保護(hù)、監(jiān)控和擴(kuò)展您的微服務(wù)。 以下是Ocelot的一些主要功能: 路由管理

    2024年01月19日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包