記錄---Vue3對接UE,通過MQTT完成通訊
????? 寫在開頭
點贊 + 收藏 === 學會??????
概述
一個基于Vue3的實時視頻流顯示系統,主要用于連接和顯示Unreal Engine (UE) 服務器的實時渲染內容。該頁面集成了PixelStreaming技術和MQTT通信協議,提供了完整的視頻流控制和交互功能。
主要功能
- 實時視頻流顯示:連接UE服務器,顯示實時渲染的3D場景
- 協議支持:支持PixelStreaming連接
- MQTT通信:通過MQTT協議進行消息通信和控制
- 連接狀態監控:實時顯示UE和MQTT連接狀態
- 錯誤處理與重連:自動處理連接錯誤并嘗試重連
快速開始
安裝依賴
npm install @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 npm install @epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.3 npm install mqtt
基本使用
- 確保UE服務器運行
- 確保MQTT服務器運行
技術架構
核心技術棧
- 前端框架: Vue 3 (Composition API)
- 視頻流技術: Epic Games PixelStreaming
- 消息協議: MQTT
連接方式
- PixelStreaming鏈接
- MQTT連接(消息通信)
代碼詳情
1. 頁面結構
<template>鏈接鏈接
<div class="scene-display-container">
<!-- 連接狀態 -->
<div class="connection-status">
<span>UE: {{ ueStatus }}</span>
<span>MQTT: {{ mqttStatus }}</span>
</div>
<!-- 視頻流容器 -->
<div class="video-container">
<div id="streamingVideo" class="streaming-video"></div>
<!-- 錯誤狀態 -->
<div v-if="errorMessage" class="error-overlay">
<p>{{ errorMessage }}</p>
<button @click="reconnect">重新連接</button>
</div>
</div>
</div>
</template>
說明:
connection-status:顯示UE和MQTT的連接狀態video-container:視頻流顯示容器error-overlay:錯誤狀態覆蓋層,提供重新連接功能
2. 響應式數據
// 響應式數據
const errorMessage = ref('') // 存儲錯誤信息
const ueStatus = ref('未連接') // UE連接狀態
const mqttStatus = ref('未連接') // MQTT連接狀態
// 實例
let pixelStreaming = null // PixelStreaming實例
let mqttClient = null // MQTT客戶端實例
3. UE連接初始化
// 初始化UE連接
const initPixelStreaming = () => {
try {
const style = new PixelStreamingApplicationStyle();
style.applyStyleSheet();
Logger.SetLoggerVerbosity(1);
const config = new Config({ useUrlParams: false });
config.setFlagEnabled(Flags.AutoPlayVideo, true);
config.setFlagEnabled(Flags.AutoConnect, true);
config.setTextSetting(TextParameters.SignallingServerUrl, "此處輸入UE服務器地址");
config.setFlagEnabled(Flags.HoveringMouseMode, ControlSchemeType.HoveringMouse);
config.setFlagEnabled(Flags.MouseInput, true);
config.setFlagEnabled(Flags.KeyboardInput, true);
config.setFlagEnabled(Flags.TouchInput, true);
config.setFlagEnabled(Flags.GamepadInput, false);
config.setFlagEnabled(Flags.XRControllerInput, false);
pixelStreaming = new PixelStreaming(config);
const application = new Application({
stream: pixelStreaming,
settingsPanelConfig: { isEnabled: false, visibilityButtonConfig: { creationMode: UIElementCreationMode.Disable } },
statsPanelConfig: { isEnabled: false, visibilityButtonConfig: { creationMode: UIElementCreationMode.Disable } },
fullScreenControlsConfig: { creationMode: UIElementCreationMode.Disable },
xrControlsConfig: { creationMode: UIElementCreationMode.Disable },
videoQpIndicatorConfig: { disableIndicator: true },
});
const container = document.getElementById("streamingVideo");
if (container) {
container.innerHTML = '';
container.appendChild(application.rootElement);
}
setupPixelStreamingEvents();
} catch (error) {
errorMessage.value = `UE連接失敗: ${error}`;
}
}
配置說明:
AutoPlayVideo: true:自動播放視頻AutoConnect: true:自動連接SignallingServerUrl:信令服務器地址HoveringMouseMode:鼠標懸停模式- 各種輸入控制:鼠標、鍵盤、觸屏等
4. 事件監聽器設置
// 設置PixelStreaming事件監聽器
const setupPixelStreamingEvents = () => {
if (!pixelStreaming) return
pixelStreaming.addEventListener('streamReady', () => {
ueStatus.value = '已連接'
errorMessage.value = ''
})
pixelStreaming.addEventListener('connectionEstablished', () => {
ueStatus.value = '已連接'
errorMessage.value = ''
})
pixelStreaming.addEventListener('connectionClose', () => {
ueStatus.value = '連接斷開'
})
pixelStreaming.addEventListener('connectionError', (error) => {
ueStatus.value = '連接失敗'
errorMessage.value = `UE連接錯誤: ${error}`
})
pixelStreaming.addEventListener('webRTCConnected', () => {
ueStatus.value = '已連接'
})
pixelStreaming.addEventListener('webRTCDisconnected', () => {
ueStatus.value = '連接斷開'
})
}
事件說明:
streamReady:視頻流準備就緒connectionEstablished:連接建立成功connectionClose:連接關閉connectionError:連接錯誤webRTCConnected:WebRTC連接成功webRTCDisconnected:WebRTC連接斷開
5. MQTT連接初始化
// 初始化MQTT連接
const initMqtt = () => {
try {
const options = {
username: 'admin',
password: 'public',
clientId: `vue_client_${Math.random().toString(16).substr(2, 8)}`,
clean: true,
reconnectPeriod: 5000,
connectTimeout: 30 * 1000,
keepalive: 60,
protocolVersion: 4
}
mqttClient = mqtt.connect('此處輸入MQTT地址', options) // 地址末尾需要加:/mqtt
mqttClient.on('connect', () => {
mqttStatus.value = '已連接'
mqttClient.subscribe('此處輸入訂閱主題的路徑')
})
mqttClient.on('error', (error) => {
mqttStatus.value = '連接失敗'
})
mqttClient.on('close', () => {
mqttStatus.value = '連接斷開'
})
mqttClient.on('message', (topic, message) => {
// 處理MQTT消息
console.log(`收到MQTT消息 [${topic}]: ${message.toString()}`)
})
} catch (error) {
mqttStatus.value = '初始化失敗'
}
}
MQTT配置說明:
username/password:MQTT認證信息clientId:客戶端唯一標識reconnectPeriod:重連間隔(5秒)connectTimeout:連接超時(30秒)keepalive:心跳間隔(60秒)
6. 重新連接功能
const reconnect = () => {
errorMessage.value = ''
if (pixelStreaming) {
try {
pixelStreaming.close()
} catch (error) {
console.warn('PixelStreaming斷開連接時出錯:', error)
}
pixelStreaming = null
}
if (mqttClient) {
mqttClient.end()
mqttClient = null
}
ueStatus.value = '未連接'
mqttStatus.value = '未連接'
setTimeout(() => {
initPixelStreaming()
initMqtt()
}, 1000)
}
重連流程:
- 清空錯誤信息
- 關閉現有連接
- 重置狀態
- 延遲1秒后重新初始化
7. 生命周期管理
// 生命周期
onMounted(() => {
initPixelStreaming()
initMqtt()
})
onUnmounted(() => {
if (pixelStreaming) {
try {
pixelStreaming.close()
} catch (error) {
console.warn('PixelStreaming清理時出錯:', error)
}
}
if (mqttClient) {
mqttClient.end()
}
})
說明:
onMounted:組件掛載時初始化連接onUnmounted:組件卸載時清理連接
常見問題及解決方案
1. 連接超時問題
// 檢查網絡連接
const checkNetworkConnection = () => {
const testUrl = 'wss://192.168.110.176'
const testSocket = new WebSocket(testUrl)
testSocket.onopen = () => {
console.log('網絡連接正常')
testSocket.close()
}
testSocket.onerror = (error) => {
console.log(`網絡連接失敗: ${error}`)
console.log('請檢查服務器地址和網絡連接')
}
}
2. MQTT連接失敗
// MQTT連接測試
const testMqttConnection = () => {
const testClient = mqtt.connect('ws://192.168.110.176:8083/mqtt', {
username: 'admin',
password: 'public',
clientId: `test_client_${Date.now()}`,
clean: true,
connectTimeout: 5000
})
testClient.on('connect', () => {
console.log('MQTT連接成功')
testClient.end()
})
testClient.on('error', (error) => {
console.log(`MQTT連接失敗: ${error.message}`)
console.log('請檢查MQTT服務器狀態和認證信息')
testClient.end()
})
}
自動重連機制
WebSocket自動重連
nativeWebSocket.onclose = (event) => {
console.log(`UE WebSocket連接已關閉 (代碼: ${event.code})`)
isConnected.value = false
connectionStatus.type = 'danger'
connectionStatus.text = '連接斷開'
// 自動重連
if (event.code !== 1000) { // 不是正常關閉
console.log('5秒后嘗試重新連接...')
setTimeout(() => {
if (!isConnected.value) {
initNativeWebSocket()
}
}, 5000)
}
}
MQTT自動重連
const mqttOptions = {
reconnectPeriod: 5000, // 5秒重連間隔
connectTimeout: 30 * 1000, // 30秒連接超時
keepalive: 60 // 60秒心跳
}
本文轉載于:https://juejin.cn/post/7550571202013397043
如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。


浙公網安備 33010602011771號