ASP.NET SignalR依賴JQ,故小程序不能直接使用。
uniapp版
SignalR的構建就不多說了,網上多得是。
原理:仿照官方JS訪問服務器的方式,先用get方式請求negotiate接口,獲取websocket的token,再拼接ws連接得到微信能用的ws或者wss連接了,接下來看微信小程序接口。
注意事項:
1.微信小程序本地測試不需要wss的,直接本機運行項目,用局域網網址訪問就可以了。
2.websocket需要IIS8才能支持,IIS Express可以用,但需要配置一下用IP訪問 (微信內不能用localhost訪問)
了解websocket機制
假設我在web端有一個聊天室頁面,假設地址為https://www.xxx.com/chat.html,由於后端Startup.cs使用的是默認目錄signalr

using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(Star.Web.Startup))] namespace Star.Web { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR();//啟動SignalR默認目錄:/signalr } } }
瀏覽器F12打開(以谷歌為例),點擊Network,然后刷新頁面或在頁面發送一個消息,在下面Name里分別會出現negotiate開頭和connect開頭的Url。
1)點擊negotiate開頭的url,在頭文件中(Headers)的General的RequestURL,顯示訪問地址是:
//signalr的negotiate https://www.text.com/signalr/negotiate?clientProtocol=1.5&connectionData=[{"name":"chatHub"}]&_=1576127697147
整理后的含義為:https://域名/signalr/negotiate?clientProtocol=1.5&connectionData=[{"name":"Hub名字"}]&_=時間戳
其中:Hub名字就是繼承Hub類里的[HubName("Hub名字")],encodeURIComponent()編碼
2)點擊connect開頭的url,在頭文件中(Headers)的General的RequestURL,顯示訪問地址是:
//signalr的connect wss://www.test.com/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=……&connectionData=[{"name":"chatHub"}]&tid=1
整理后的含義為:wss://域名/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=Token字符串&connectionData=[{"name":"Hub名字"}]&tid=1
其中:Token字符串就是上一個請求返回的結果;tid經測試取值在0~10之間,待進一步測試.
Vue page:把連接改為你的連接
1 <template> 2 <view> 3 <button type="primary" @tap='getSignalR'>訪問signalR</button> 4 <button type="primary" @tap='openWebSocket'>打開websocket</button> 5 <input type="text" v-model="msg" placeholder="請輸入消息"/> 6 <button type="primary" @tap='sendMsg()'>發送</button> 7 8 <view> 9 <view v-for="item in result"> 10 <text>{{item}}</text> 11 </view> 12 </view> 13 </view> 14 </template> 15 16 <script> 17 var _this; 18 export default { 19 data() { 20 return { 21 result: [], 22 socketOpen:false, 23 msg:"", 24 websocketData: {}, 25 26 } 27 }, 28 onLoad() { 29 _this = this; 30 }, 31 methods: { 32 getSignalR() { 33 let url = 'http://192.168.31.171:8088/signal/negotiate?clientProtocol=1.5&connectionData=[{"name":"chathub"}]&_=1564798079763' 34 uni.request({ 35 url: url, 36 data: { 37 text: 'uni.request' 38 }, 39 header: { 40 //自定義請求頭信息 41 }, 42 success: (res) => { 43 console.log(res); 44 _this.websocketData = res.data; 45 _this.result.push( 'request success'); 46 } 47 }); 48 }, 49 openWebSocket() { 50 let token = encodeURIComponent(_this 51 .websocketData.ConnectionToken) 52 let url = 'ws://192.168.31.171:8088/signal/connect?transport=webSockets&clientProtocol=1.5&connectionData=[{"name":"chatHub"}]&connectionToken=' + 53 token + '&tid=1' 54 console.log(url) 55 uni.connectSocket({ 56 url: url 57 }); 58 uni.onSocketOpen(function(res) { 59 console.log(res); 60 _this.socketOpen = true; 61 console.log('WebSocket連接已打開!'); 62 _this.result.push("WebSocket連接已打開!"); 63 }); 64 uni.onSocketError(function(res) { 65 console.log(res); 66 _this.result.push('WebSocket連接打開失敗,請檢查!') 67 console.log('WebSocket連接打開失敗,請檢查!'); 68 }); 69 70 uni.onSocketMessage(function(res) { 71 _this.result.push('收到服務器內容:' + res.data ); 72 73 console.log('收到服務器內容:' + res.data); 74 }); 75 76 }, 77 78 sendMsg(){ 79 if(!_this.socketOpen) 80 return; 81 82 uni.sendSocketMessage({ 83 data: _this.msg 84 }); 85 } 86 } 87 } 88 </script> 89 <style> 90 </style>
后續簡單說下發送和接收消息體格式:
客戶端向服務端發送消息體
格式:{"H":"chathub","M":"SendToOther","A":[{"Msg":"Hello World!","UserId":"085ac7c7-94be-4a41-93c7-c207939714b9"}],"I":2}
參數解釋:"H":"ChatHub" 是集線器hub類,"M":"SendToOther"是集線器hub類暴露的方法,"A"是提交服務端的數據
服務端返回客戶端的消息體
格式:{"C":"d-26707556-E,0|BP,5B|BQ,1","M":[{"H":"ChatHub","M":"UpdateLocalhost","A":[{"UserId":"51c0b472-ea1c-424d-8dc4-157ce0cf1ff2","SendTime":"2020-06-12 16:12:41","Msg":"Hello World!"}]}]}
參數解釋:"H":"ChatHub" 是集線器hub類,"M":"UpdateLocalhost"是服務端返回客戶端的標識,"A"是服務端返回的數據