公司的接口已經集成了SignalR,再單獨弄websocket需要改太多,直接引用不了官網的js,查看過源碼,會用到JQuery和document,UniApp和微信小程序都不支持。有文章說官方的Core版signalR是支持小程序的方式引用了,去掉了對JQ的依賴,但是公司的項目不是Core的。
SignalR的構建就不多說了,網上多得是,原文也有。
原理:仿照官方JS訪問服務器的方式,先用get方式請求negotiate接口,獲取websocket的token,再拼接ws連接得到微信能用的ws或者wss連接了,接下來看微信小程序接口。
注意項:
1.微信小程序本地測試不需要wss的,直接本機運行項目,用局域網網址訪問就可以了。
2.websocket需要IIS8才能支持,IIS Express可以用,但需要配置一下用IP訪問 (微信內不能用localhost訪問),附上配置方式。
測試頁面:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.4.1.js"></script>
</head>
<body>
<div>
<h1>Echo service</h1>
<div>
<input type="text" id="text" />
<button id="send">Send</button>
</div>
<script>
var connection = $.connection("/signal");
connection.logging = true;
connection.debug = true;
connection.transport = 'webSockets';
console.log( connection)
//客戶端接收消息
connection.received(function (data) {
$(document.body).append(data+"<br/>");
});
//連接錯誤處理
connection.error(function (err) {
alert('與服務器連接報錯:'+err.message);
});
//連接成功
connection.start().done(function () {
$('#send').click(function () {
var val = $('#text').val();
//向服務器端發送消息
connection.send(val);
});
});
</script>
</div>
</body>
</html>
Vue page:把連接改爲你的連接
<template>
<view>
<button type="primary" @tap='getSignalR'>訪問signalR</button>
<button type="primary" @tap='openWebSocket'>打開websocket</button>
<input type="text" v-model="msg" placeholder="請輸入消息"/>
<button type="primary" @tap='sendMsg()'>發送</button>
<view>
<view v-for="item in result">
<text>{{item}}</text>
</view>
</view>
</view>
</template>
<script>
var _this;
export default {
data() {
return {
result: [],
socketOpen:false,
msg:"",
websocketData: {},
}
},
onLoad() {
_this = this;
},
methods: {
getSignalR() {
let url = 'http://192.168.2.102:11849/signal/negotiate?clientProtocol=2.1&_=1564798079763'
uni.request({
url: url,
data: {
text: 'uni.request'
},
header: {
'custom-header': 'hello' //自定義請求頭信息
},
success: (res) => {
console.log(res);
_this.websocketData = res.data;
_this.result.push( 'request success');
}
});
},
openWebSocket() {
let token = encodeURIComponent(_this
.websocketData.ConnectionToken)
let url = 'ws://192.168.2.102:11849/signal/connect?transport=webSockets&clientProtocol=2.1&connectionToken=' +
token + '&tid=1'
console.log(url)
uni.connectSocket({
url: url
});
uni.onSocketOpen(function(res) {
console.log(res);
_this.socketOpen = true;
console.log('WebSocket連接已打開!');
_this.result.push("WebSocket連接已打開!");
});
uni.onSocketError(function(res) {
console.log(res);
_this.result.push('WebSocket連接打開失敗,請檢查!')
console.log('WebSocket連接打開失敗,請檢查!');
});
uni.onSocketMessage(function(res) {
_this.result.push('收到服務器內容:' + res.data );
console.log('收到服務器內容:' + res.data);
});
},
sendMsg(){
if(!_this.socketOpen)
return;
uni.sendSocketMessage({
data: _this.msg
});
}
}
}
</script>
<style>
</style>
PS:
如果連接不上,請檢查IIS或者IIS Express是否支持websocket;用測試頁查看signalR的連接方式是什麼,
如圖,connect請求中,如果支持websocket會默認用websocket的,其他的話,請看transport參數。
結果: