SignalR
-
SignalR 面向 ES6。 对于不支持 ES6 的浏览器,请将库转译为 ES5。
-
SignalR 支持以下用于处理实时通信的技术(按正常回退的顺序):
WebSockets Server-Sent Events 长轮询
-
SignalR 自动选择服务器和客户端能力范围内的最佳传输方法。
-
SignalR提供了非常良好的Api以供远程调用(RPC) 。 RPC 从服务器端 .NET Core 代码调用客户端上的函数。 提供多个受支持的平台,其中每个平台都有各自的客户端 SDK。 因此,RPC 调用所调用的编程语言有所不同。
-
SignalR 提供两种内置中心协议:基于 JSON 的文本协议和基于
MessagePack
的二进制协议。
WebSocket和SignalR
WebSocket本质上是一个基于TCP的持久化协议,相对于HTTP这种非持久的协议来说,它能够更好的节省服务器资源和带宽,并且真正实现实时通信。最大的缺点就是对旧版本浏览器不支持。至此SignalR的出现,完美的解决了种浏览器的问题,SignalR不仅可以实现WebSocket的所有功能,还对旧版本浏览器做了支持。SignalR可自动或手动选择使用WebSocket传输还是其他替代方式传输,以实现实时Web技术。
signal的使用
用例为电视机与服务器交互。创建一个signalR.js
文件
import { useMessageStore } from '@/store'
import Version from '@/api/Version'
const signalRUrl = `${import.meta.env.VITE_BASEURL}/TVCenterHub`
export async function startSignalRConnection() {
const messageStore = useMessageStore()
const res = await uni.request({
method: 'POST',
url: `${signalRUrl}/negotiate`
})
uni.connectSocket({
url: `${signalRUrl.replace('http', 'ws')}?id=${res.data.connectionId}`,
method: 'GET',
success(res) {}
})
uni.onSocketOpen(function (res) {
uni.sendSocketMessage({
data: `{"protocol":"json", "version":1}${String.fromCharCode(0x1e)}`
})
// sendMessageToTV()
})
uni.onSocketMessage(function (res) {
const msg = JSON.parse(res.data.split(String.fromCharCode(0x1e))[0])
if (msg.target === 'SendMessageToTV') {
messageStore.setMessage(msg.arguments[0])
}
})
uni.onSocketClose(function (res) {
console.log('连接关闭!')
uni.sendSocketMessage({
data: `{"protocol":"json", "version":1}${String.fromCharCode(0x1e)}`
})
attemptReconnect(0)
})
}
let reconnectAttempts = 0
const maxReconnectAttempts = 5 // 可配置的最大重试次数
function attemptReconnect() {
if (reconnectAttempts < maxReconnectAttempts) {
reconnectAttempts++
setTimeout(async () => {
try {
await startSignalRConnection() // 调用原函数重新连接
} catch (err) {
console.error('重连失败:', err)
attemptReconnect() // 若连接失败,继续尝试
}
}, 3000) // 间隔时间可调整,这里设置为3秒
} else {
console.warn('达到最大重试次数,停止重连')
}
}
// 添加一个方法用于向服务器发送消息
async function sendMessageToTV(messageContent, connection) {
await Version.PowerOnAnnouce()
}
-
将环境变量和固定字符串组合成一个完整的 URL。
import.meta.env
是 Vite 构建工具提供的特性,用于访问环境变量。VITE_BASEURL
是一个预先定义的环境变量,通常在项目的.env
文件中配置。 -
onSocketMessage
监听返回的数据目标是不是针对当前客户端,是的话将返回的数据做处理。这里通过Message
的store
对返回的数据类型做判断,展示对应的电视机界面,并在界面中可以通过getMessage
获取展示数据import { defineStore } from 'pinia' export const useMessageStore = defineStore('messageState', { state: () => { return { messageObject: { ... } } }, getters: {}, actions: { setMessage(messageObject: Object) { this.messageObject = messageObject const pages = getCurrentPages() if (messageObject.hasOwnProperty('...')) if (pages[0]?.route !== 'pages/pick/index') uni.navigateTo({ url: '/pages/pick/index' }) else if (pages[0]?.route !== 'pages/index/index') uni.navigateTo({ url: '/pages/index/index' }) }, getMessage() { return this.messageObject } } })