ASP.NET Core在支付宝小程序中使用signalR
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');