如何在Expo应用单个路由中集成WebSocket(后端基于Express.js)
整合方案:Express后端+Expo前端对接Azure IoT Hub实时数据(WebSocket)
一、后端整合:Express + WebSocket + Azure IoT Hub
WebSocket和Express REST路由可以共存,共用同一个HTTP服务器,不会互相干扰。以下是具体实现步骤:
1. 安装依赖
npm install ws azure-iothub
2. 修改server.js核心代码
const express = require('express'); const http = require('http'); const WebSocket = require('ws'); const { IoTHubServiceClient } = require('azure-iothub'); const app = express(); const server = http.createServer(app); // 创建共用的HTTP服务器 const wss = new WebSocket.Server({ server }); // 挂载WebSocket服务到同一服务器 // 初始化Azure IoT Hub Service Client const connectionString = '<你的Azure IoT Hub连接字符串>'; const serviceClient = IoTHubServiceClient.fromConnectionString(connectionString); // 存储活跃的WebSocket客户端 const clients = new Set(); // 监听Azure IoT Hub设备消息 async function startIoTMessageListener() { const receiver = serviceClient.getNotificationReceiver(); receiver.on('message', (msg) => { // 格式化IoT消息并推送给所有客户端 const messageData = JSON.stringify({ deviceId: msg.enqueuedDeviceId, payload: JSON.parse(msg.data.toString()), timestamp: msg.enqueuedTimeUtc }); clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(messageData); } }); receiver.complete(msg); }); receiver.on('error', (err) => { console.error('IoT Hub消息接收错误:', err); }); } // 处理WebSocket连接 wss.on('connection', (ws) => { console.log('新WebSocket客户端连接'); clients.add(ws); ws.on('close', () => { console.log('WebSocket客户端断开'); clients.delete(ws); }); ws.on('error', (err) => { console.error('WebSocket错误:', err); clients.delete(ws); }); }); // 保留原有REST路由逻辑 app.use(express.json()); app.get('/api/historical-data', (req, res) => { // 原REST API业务逻辑 res.json({ status: 'ok', data: '历史数据示例' }); }); // 启动服务 const PORT = process.env.PORT || 3000; server.listen(PORT, () => { console.log(`服务器运行在端口 ${PORT}`); startIoTMessageListener().catch(err => console.error('IoT监听启动失败:', err)); });
二、前端Home页面整合WebSocket(Expo React Native)
仅在home.js中实现WebSocket实时数据接收,其他页面继续使用原有REST API:
import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet } from 'react-native'; const HomeScreen = () => { const [realTimeData, setRealTimeData] = useState(null); let ws = null; useEffect(() => { // 初始化WebSocket连接(开发用ws,生产用wss) ws = new WebSocket('ws://<你的后端地址>:3000'); ws.onopen = () => console.log('WebSocket连接成功'); ws.onmessage = (event) => { const data = JSON.parse(event.data); setRealTimeData(data); }; ws.onerror = (error) => console.error('WebSocket错误:', error); ws.onclose = () => { console.log('WebSocket连接关闭'); // 可选:添加自动重连逻辑 setTimeout(() => { /* 重新初始化连接 */ }, 5000); }; // 组件卸载时关闭连接 return () => ws?.close(); }, []); return ( <View style={styles.container}> <Text style={styles.title}>实时IoT数据</Text> {realTimeData ? ( <View style={styles.dataCard}> <Text>设备ID: {realTimeData.deviceId}</Text> <Text>数据内容: {JSON.stringify(realTimeData.payload)}</Text> <Text>上报时间: {realTimeData.timestamp}</Text> </View> ) : ( <Text>连接中...</Text> )} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, }, title: { fontSize: 22, fontWeight: 'bold', marginBottom: 20, }, dataCard: { gap: 10, padding: 18, backgroundColor: '#f5f5f5', borderRadius: 10, width: '100%', }, }); export default HomeScreen;
三、关键注意事项
- 路由互不干扰:WebSocket和REST API共用同一HTTP服务器,服务器会自动区分请求类型——Express处理常规HTTP请求,WebSocket处理
Upgrade协议请求,完全隔离,不会影响原有REST路由。 - Azure IoT Hub配置:确保你的Service Client拥有
service connect权限,能够接收设备上报的消息;如果需要监听特定设备,可以在Receiver中添加筛选逻辑。 - 前端稳定性:建议添加WebSocket断连自动重连逻辑,避免因网络波动丢失实时数据;生产环境务必使用
wss://加密连接。 - 其他页面无改动:其他页面继续使用
fetch或axios调用原有REST API,不需要做任何调整。
内容的提问来源于stack exchange,提问作者onomatopoeia_truck
相关产品推荐
相关产品推荐

