公司的接口已经集成了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参数。
结果: