1. 程式人生 > >ASP.NET Core SignalR 與微信小程式互動

ASP.NET Core SignalR 與微信小程式互動

點選上方“程式設計師大咖”,選擇“置頂公眾號”

關鍵時刻,第一時間送達!640?640?wx_fmt=gif

來源:James.Ying

文:cnblogs.com/inday/p/signalr-wechat-miniapp.html

程式設計師大咖整理髮布,轉載請聯絡作者獲得授權

什麼是ASP.NET Core SignalR

ASP.NET Core SignalR 是微軟開發的一套基於ASP.NET Core的與Web進行實時互動的類庫,它使我們的應用能夠實時的把資料推送給Web客戶端。

功能

  • 自動管理連線

  • 允許同時廣播到所有客戶端

  • 也可以廣播到指定的組或者特定的客戶端

  • 在Github上開源,傳送門(https://github.com/aspnet/signalr)

SignalR 提供了多種連線方式,在現代化應用中,WebSocket是最佳的傳輸協議,在客戶端無法實現WebSocket協議的時候,SignalR就會採取其他方式,比如Server-Sent或者長輪詢(在ws未出現之前,我們討論的推拉模式)

中心 Hubs

SignalR是採用中心客戶端和伺服器進行通訊。

中心是一種高階的管道,允許客戶端和伺服器之間相互呼叫方法。

中心通過強型別引數傳遞給方法,進行模型繫結

Hubs.Clients

Clients屬性包含了所有的客戶端連線資訊,它包含了3個屬性:

  • All 所有客戶端

  • Caller 進行此次請求的客戶端

  • Others 排除此次請求客戶端的其他客戶端

包含了多個方法:

  • = AllExcept 在指定的連線除外的所有連線的客戶端上呼叫方法

  • Client 在特定連線的客戶端上呼叫方法

  • Clients 在特定連線的客戶端上呼叫方法

  • Group 呼叫指定的組中的一種對所有連線方法

  • GroupExcept 呼叫中指定的組,除非指定連線到的所有連線的方法

  • Groups 呼叫一種對多個組的連線方法

  • OthersInGroup 呼叫一種對一組的連線,不包括客戶端呼叫 hub 方法方法

  • User 呼叫一種對與特定使用者關聯的所有連線方法

  • Users 呼叫一種對與指定的使用者相關聯的所有連線方法

每個屬性和方法返回的物件都包含一個SendAsync方法,可以對客戶端進行呼叫。

HubContext

可以在應用其他地方通過使用IHubContext,達到呼叫Hub的目的。

兩種協議

  • 文字協議:JSON

  • 二進位制協議:MessagePack(https://msgpack.org/)

MessagePack類似於JSON,但傳輸比JSON更快,資料大小比JSON更小

伺服器事項

  • 建立的Hub必須繼承Microsoft.AspNetCore.SignalR.Hub,Hub類已經包含了管理連線、組和傳送接收訊息的屬性及事件

  • 在Hub中使用的方法應該儘量使用非同步的方式,因為SignalR在傳送和接收訊息的時候使用的是非同步方法。

  • 在Startup.ConfigureServices中通過services.AddSignalR對SignalR進行註冊

  • 在Startup.Configure中通過app.UseSignalR方法對Hub路由進行配置

程式碼解析

微軟官方示範(https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-2.1&tabs=visual-studio)中的ChatHub:

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRChat.Hubs
{
    public class ChatHub : Hub
    {
        //服務端方法
        public async Task SendMessage(string user, string message)
        {
            //ReceiveMessage 為客戶端方法,讓所有客戶端呼叫這個方法
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

上述程式碼為當收到客戶端發來的SendMessage請求後(傳送聊天資訊),我們把訊息傳送到所有客戶端,讓他們呼叫自身的ReceiveMessage方法。

使用者標識

通常情況下,在使用者進行連線後,Connection會儲存使用者的使用者標識,以便對特定使用者進行傳送訊息。

可以實現IUserIdProvider來自定義獲取使用者的方法,例如:

public class CustomUserIdProvider : IUserIdProvider
{
    public virtual string GetUserId(HubConnectionContext connection)
    {
        return connection.User?.FindFirst(ClaimTypes.Email)?.Value;
    }
}

在Startup.ConfigureServices中註冊:

services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();

Group 分組

分組類似於聊天室中的每個房間,通過分組,我們可以給特定小組傳送訊息。

使用者標識和組名稱都是區分大小寫的。

微信小程式與SignalR互動

小程式因為無法直接使用websocket,所以無法使用signalR.js,你可以試著把signalR.js中的webcosket使用部分換成wx.xxSocketxxx。

參考了算神(http://blog.lishewen.com/)的程式碼(https://github.com/lishewen/WeChatMiniAppSignalRClient)後

歸了一個小類庫,方便大家使用,原始碼較長,放到github上(https://github.com/JamesYing/signalR4Miniapp)。

如何使用

呼叫類庫

在要使用的頁面上:

///引入這個類庫
var signalR = require('../../lib/signalr/signalr.js')
///例項化一個物件
let _client = new signalR.signalR();

建立 一個對映方法

這是為了讓小程式收到SignalR的訊息之後進行回撥

callMethods(methods, args) {
        console.log(methods, args);
        let self = this;
        switch (methods) {
            case 'sayHello':
                self.sayHello(args[0]);
                break;
        }
    },

例子裡有一個sayHello方法,我們用字串作為key。

進行連線

_client.connection(url, methodMapping);
  • url : signalR伺服器

  • methodMapping : 方法和字串之間的Mapping

呼叫SignalR方法

  • _client.call(methodName, args, success, fail)

  • methodName:遠端方法名

  • args:引數,這裡注意一定要陣列格式

  • success:呼叫成功後的回撥

  • fail:失敗後的回撥

寫在最後

類庫可能並不完善,你可以在github上提issue,我會跟進的,有好的修改方式,可以PR我。