ASP.NET Core在支付寶小程式中使用signalR

来源:https://www.cnblogs.com/myhalo/archive/2019/07/15/11191988.html
-Advertisement-
Play Games

Github有一個經過重寫的微信小程式SignalR的js類庫 https://github.com/liangshiw/SignalRMiniProgram-Client 於是我把他改成支付寶小程式的版本,上面這個項目的核心代碼基本沒有變,只是小程式開放介面改了一下,在支付寶小程式就能跑起來了 把 ...


Github有一個經過重寫的微信小程式SignalR的js類庫

https://github.com/liangshiw/SignalRMiniProgram-Client

於是我把他改成支付寶小程式的版本,上面這個項目的核心代碼基本沒有變,只是小程式開放介面改了一下,在支付寶小程式就能跑起來了

把下麵的js代碼複製到你的支付寶小程式即可(使用方法在下麵):

【代碼】

  1 const protocal = {
  2   protocol: "json",
  3   version: 1
  4 };
  5 
  6 const MessageType = {
  7   /** Indicates the message is an Invocation message and implements the {@link InvocationMessage} interface. */
  8   Invocation: 1,
  9   /** Indicates the message is a StreamItem message and implements the {@link StreamItemMessage} interface. */
 10   StreamItem: 2,
 11   /** Indicates the message is a Completion message and implements the {@link CompletionMessage} interface. */
 12   Completion: 3,
 13   /** Indicates the message is a Stream Invocation message and implements the {@link StreamInvocationMessage} interface. */
 14   StreamInvocation: 4,
 15   /** Indicates the message is a Cancel Invocation message and implements the {@link CancelInvocationMessage} interface. */
 16   CancelInvocation: 5,
 17   /** Indicates the message is a Ping message and implements the {@link PingMessage} interface. */
 18   Ping: 6,
 19   /** Indicates the message is a Close message and implements the {@link CloseMessage} interface. */
 20   Close: 7,
 21 }
 22 
 23 
 24 export class HubConnection {
 25 
 26   constructor() {
 27     this.openStatus = false;
 28     this.methods = {};
 29     this.negotiateResponse = {};
 30     this.url = "";
 31     this.invocationId = 0;
 32     this.callbacks = {};
 33   }
 34 
 35   start(url, queryString) {
 36     var negotiateUrl = url + "/negotiate";
 37     if (queryString) {
 38       for (var query in queryString) {
 39         negotiateUrl += (negotiateUrl.indexOf("?") < 0 ? "?" : "&") + (`${query}=` + encodeURIComponent(queryString[query]));
 40       }
 41     }
 42     my.request({
 43       url: negotiateUrl,
 44       method: "POST",
 45       success: (res) => {
 46         this.negotiateResponse = res.data;
 47         this.startSocket(negotiateUrl.replace("/negotiate", ""));
 48       },
 49       fail: (res) => {
 50         console.error(`requrst ${url} error : ${res}`);
 51       }
 52     });
 53   }
 54 
 55   startSocket(url) {
 56     url += (url.indexOf("?") < 0 ? "?" : "&") + ("id=" + this.negotiateResponse.connectionId);
 57     url = url.replace(/^http/, "ws");
 58     this.url = url;
 59     if (this.openStatus) {
 60       return;
 61     }
 62 
 63     console.log(url);
 64 
 65     my.connectSocket({
 66       url: url
 67     })
 68 
 69     my.onSocketOpen(res => {
 70       console.log(`websocket connectioned to ${this.url}`);
 71       this.sendData(protocal);
 72       this.openStatus = true;
 73       this.onOpen(res);
 74     });
 75 
 76     my.onSocketClose(res => {
 77       console.log(`websocket disconnection`);
 78       this.openStatus = false;
 79       this.onClose(res);
 80     });
 81 
 82     my.onSocketError(res => {
 83       console.error(`websocket error msg: ${res}`);
 84       this.close({
 85         reason: res
 86       });
 87       this.onError(res)
 88     });
 89 
 90     my.onSocketMessage(res => this.receive(res));
 91   }
 92 
 93   on(method, fun) {
 94 
 95     let methodName = method.toLowerCase();
 96     if (this.methods[methodName]) {
 97       this.methods[methodName].push(fun);
 98     } else {
 99       this.methods[methodName] = [fun];
100     }
101   }
102 
103   onOpen(data) { }
104 
105   onClose(msg) { }
106 
107   onError(msg) { }
108 
109   close(data) {
110     if (data) {
111       console.error('closed socket: ' + data.reason);
112     }
113 
114     my.closeSocket();
115 
116     this.openStatus = false;
117   }
118 
119   sendData(data, success, fail, complete) {
120     my.sendSocketMessage({
121       data: JSON.stringify(data) + "", //
122       success: success,
123       fail: fail,
124       complete: complete
125     });
126   }
127 
128 
129   receive(data) {
130     if (data.data.length > 3) {
131       data.data = data.data.replace('{}', "")
132     }
133 
134     var messageDataList = data.data.split("");
135 
136     //迴圈處理服務端信息
137     for (let serverMsg of messageDataList) {
138       if (serverMsg) {
139         var messageData = serverMsg.replace(new RegExp("", "gm"), "")
140         var message = JSON.parse(messageData);
141 
142         switch (message.type) {
143           case MessageType.Invocation:
144             this.invokeClientMethod(message);
145             break;
146           case MessageType.StreamItem:
147             break;
148           case MessageType.Completion:
149             var callback = this.callbacks[message.invocationId];
150             if (callback != null) {
151               delete this.callbacks[message.invocationId];
152               callback(message);
153             }
154             break;
155           case MessageType.Ping:
156             // Don't care about pings
157             break;
158           case MessageType.Close:
159             console.log("Close message received from server.");
160             this.close({
161               reason: "Server returned an error on close"
162             });
163             break;
164           default:
165             console.warn("Invalid message type: " + message.type);
166         }
167       }
168     }
169   }
170 
171   send(functionName) {
172     var args = [];
173     for (var _i = 1; _i < arguments.length; _i++) {
174       args[_i - 1] = arguments[_i];
175     }
176 
177     this.sendData({
178       target: functionName,
179       arguments: args,
180       type: MessageType.Invocation,
181       invocationId: this.invocationId.toString()
182     });
183     this.invocationId++;
184   }
185 
186   invoke(functionName) {
187     var args = [];
188     for (var _i = 1; _i < arguments.length; _i++) {
189       args[_i - 1] = arguments[_i];
190     }
191 
192     var _this = this;
193     var id = this.invocationId;
194     var p = new Promise(function(resolve, reject) {
195 
196       _this.callbacks[id] = function(message) {
197         if (message.error) {
198           reject(new Error(message.error));
199         } else {
200           resolve(message.result);
201         }
202       }
203 
204       _this.sendData({
205         target: functionName,
206         arguments: args,
207         type: MessageType.Invocation,
208         invocationId: _this.invocationId.toString()
209       }, null, function(e) {
210         reject(e);
211       });
212 
213     });
214     this.invocationId++;
215     return p;
216   }
217 
218   invokeClientMethod(message) {
219     var methods = this.methods[message.target.toLowerCase()];
220     if (methods) {
221       methods.forEach(m => m.apply(this, message.arguments));
222       if (message.invocationId) {
223         // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response.
224         var errormsg = "Server requested a response, which is not supported in this version of the client.";
225         console.error(errormsg);
226         this.close({
227           reason: errormsg
228         });
229       }
230     } else {
231       console.warn(`No client method with the name '${message.target}' found.`);
232     }
233   }
234 }

【使用方法】

const hub = require('../../utils/signalr.js');

const connection = new hub.HubConnection();

//註意:這裡的apiHost不是wss或ws,是https或http
connection.start(`${apiHost}/yourHub`, { access_token: '如果有token則填寫' });

connection.onOpen = res => {
    my.showToast({
         content: '成功開啟連接'
     });
}

connection.on('伺服器的回調方法', (errorCode) => {
      my.showToast({
           content: errorCode
       });
        console.log(errorCode);
});

connection.send('Hub中的方法', '參數1', '參數2');

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.儘量在合適的場合使用單例 使用單例可以減輕載入的負擔,縮短載入的時間,提高載入的效率,但並不是所有地方都適用於單例,簡單來說,單例主要適用於以下三個方面: 控制資源的使用,通過線程同步來控制資源的併發訪問; 控制實例的產生,以達到節約資源的目的; 控制數據共用,在不建立直接關聯的條件下,讓多個不 ...
  • 前面介紹瞭如何使用畫筆在控制項上展示圖像,可是圖像來源於磁碟圖片,無法即興繪製個性化的圖案。所幸畫筆工具Graphics不僅能夠描繪圖像,還支持繪製常見的幾何形狀,也支持繪製文本字元串,除了繪製圖像用到的drawImage方法,Graphics還有下列常見的繪圖方法:setColor:設置畫筆的顏色。 ...
  • 數組元素查找(查找指定元素第一次在數組中出現的索引): 結果: ...
  • 8.4 粘包問題 粘包問題發生的原因: 1.發送端需要等緩衝區滿才發送出去,造成粘包(發送數據時間間隔很短,數據了很小,會合到一起,產生粘包),這樣接收端,就難於分辨出來了,必須提供科學的拆包機制。 即面向流的通信是無消息保護邊界的。 2.接收方不及時接收緩衝區的包,造成多個包接收(客戶端發送了一段 ...
  • 1.python介紹 Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/)是一種廣泛使用的解釋型、高級編程、通用型編程語言,由吉多、範羅蘇姆創造,第一版發佈於1991年。可以視之為一種改良(加入一些其他編程語言的優點,如面向對象)的lisp。Python的設計哲學強調代碼的可 ...
  • 題目 "String painter " 給出兩個字元串s1,s2。對於每次操作可以將 s1 串中的任意一個子段變成另一個字元。問最少需要多少步操作能將s1串變為s2串。 解析 太妙了這個題,mark一下。 這個題先考慮怎麼由空串轉化s2, $f[i][j]$表示從空串到s2最少的次數, 則有$f[ ...
  • 3.9各類型數據方法補充,轉換,分類,編碼,坑中菜 3.9.1數據類型方法補充 1.str:不可變 補充方法 1. s1.capitalize():首字母大寫 2. s1.title(): 每個單詞首字母大寫 3. s1.swapcase():大小寫反轉 4. s1.center():居中 填充 5 ...
  • 1.各種斷言方法 常用斷言方法: 方法 用途 assertEqual(a, b) 核實a == b assertNotEqual(a, b) 核實a != b assertTrue(x) 核實x為True assertFalse(x) 核實x為False asseertIn(item, list) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...