.NET SignalR與微信小程序websocket聊天


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
        }
    }
}
View Code

瀏覽器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"是服務端返回的數據

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM