知识点:
SignalR是对WebSocket的封装
SignalR是对WebSocket的封装但又不只是对WebSocket的简单封装,而是支持多种服务器推送的实现方式,包括WebSocket、服务器发送事件(server-sent events)和长轮询。
UniApp并不直接支持SignalR库
因为SignalR的JavaScript客户端库(@microsoft/signalr)依赖于浏览器提供的WebSocket API,而UniApp并没有提供完整的浏览器环境,因此无法直接使用SignalR库。
解决这个问题的方法之一是使用UniApp提供的原生WebSocket API来建立与SignalR Hub的连接。
因为我们都知道 这样可以绕过SignalR的JavaScript客户端库,直接在UniApp中与SignalR Hub进行通信。
Demo代码:
以下是一个使用UniApp原生WebSocket API连接到SignalR Hub的Demo
C#服务端:
1.引用“Volo.Abp.AspNetCore.SignalR” Nuget包
2.注入SignalR服务
context.Services.AddSignalR()
.AddJsonProtocol(options =>
{
//序列化和反序列化过程中,属性名称将不会被更改
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
});
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatSignalRHub>("/chat-signalr-hub");
});
3.创建名为 ChatSignalRHub.cs 的Hub类,继承自 Hub
public class ChatSignalRHub : Hub
{
/// <summary>
/// 发送消息
/// </summary>
/// <param name="socketMessage"></param>
/// <returns></returns>
public async Task SendMessage(string socketMessage)
{
await Clients.All.SendAsync("ReceiveMessage", socketMessage);
}
}
uniapp客户端:
<template>
<view>
<input type="text" v-model="mes" placeholder="消息" />
<button @click="sendMessage(mes)">发送</button>
</view>
</template>
<script>
export default {
data() {
return {
mes:"",
heartbeatTimer: null,
}
},
mounted() {
//连接
uni.connectSocket({
url: "ws://pxfyf3.natappfree.cc/chat-signalr-hub",
method: 'GET',
success: function() {
// 监听WebSocket连接打开事件
uni.onSocketOpen(function(res) {
uni.sendSocketMessage({
data: `{"protocol":"json", "version":1}${String.fromCharCode(0x1e)}`
});
console.log('WebSocket连接已打开!');
});
}
});
//心跳检测
this.heartbeatTimer = setInterval(() => {
uni.sendSocketMessage({
data: `${JSON.stringify({arguments: [],target: "Heartbeat",type: 1,})}${String.fromCharCode(0x1e)}`
}).then(response => {
console.log('收到心跳响应:', response);
}).catch(error => {
console.error('发送心跳请求失败:', error);
// 重连
uni.connectSocket({
url: "ws://pxfyf3.natappfree.cc/chat-signalr-hub",
method: 'GET',
success: function() {}
});
// 监听WebSocket连接打开事件
uni.onSocketOpen(function(res) {
uni.sendSocketMessage({
data: `{"protocol":"json", "version":1}${String.fromCharCode(0x1e)}`
});
console.log('重连:WebSocket连接已打开!');
});
});
}, 5000);
//监听连接失败时
uni.onSocketError(function(res) {
console.log(res, 'WebSocket连接失败!');
});
//监听接收到服务端消息
uni.onSocketMessage((res) => {
var msg = res.data.replace(String.fromCharCode(0x1e), ""); //替换消息结束符
let msgData = JSON.parse(msg);
//接收消息
if (msgData.type === 1 && msgData.target == "ReceiveMessage") {
console.log('收到服务器内容:' + JSON.stringify(msgData.arguments[0]));
}
});
//监听断开
uni.onSocketClose(function(res) {
console.log('WebSocket 已关闭!');
});
},
onUnload() {
//关闭 WebSocket 连接
uni.closeSocket(function(res) {
console.log('WebSocket 已关闭!');
});
//停止心跳检测
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
console.log('已停止心跳检测!');
}
},
methods: {
//发送消息
sendMessage(socketMessage) {
// 通过 WebSocket 连接发送数据
uni.sendSocketMessage({
data: `${JSON.stringify({arguments: [socketMessage],target: "SendMessage",type: 1,})}${String.fromCharCode(0x1e)}`
});
console.log('(' + socketMessage + ')消息已发送');
}
}
}
</script>
效果:
uniapp客户端发送到浏览器客户端效果图:
浏览器客户端教程:https://mp.weixin.qq.com/s/GtDw-TjlerxsrDVTwee86w