You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过MQTT、Node.js、Socket.IO向Flutter发送实时数据并解决接收异常问题

服务端问题修复

你现有服务端存在4个核心问题:

  • 未启动HTTP服务监听指定端口,Socket.IO服务根本未对外暴露
  • 未配置Socket.IO跨域规则,跨域请求会被直接拦截
  • MQTT客户端连接成功后未订阅目标主题,无法触发message事件回调
  • 模板字符串语法错误(单引号包裹模板变量,未使用反引号,仅影响日志输出不影响功能)

修正后的完整服务端代码:

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
var http = require('http');
const port = process.argv.slice(2)[0] || 3000; // 缺省端口兜底
const app = express();
app.use(bodyParser.json());

const mqtt = require('mqtt')
const client = mqtt.connect('mqtt://broker.hivemq.com')
var firebase = require('firebase');
const server = http.Server(app)
// 配置Socket.IO允许跨域
const socketIo = require('socket.io')(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
})

// MQTT连接成功后订阅目标主题,替换成你实际的业务主题
client.on('connect', () => {
  client.subscribe('your/Target/MQTT/Topic', (err) => {
    if (!err) console.log('MQTT主题订阅成功')
  })
})

function mqtt_messsageReceived(topic, message, packet) {
    if(message){
      let messageObject = JSON.parse(message)
      insertMessage(topic, messageObject, packet)
      // 全局广播给所有已连接的客户端
      socketIo.emit('geocoordinateData', messageObject);
    }
}
socketIo.on('connection', (socket) =>{
  // 修复模板字符串语法,用反引号包裹
  console.log(`${socket.id} 已连接`)
  socket.emit('request', 'ok');
})

// 启动服务监听端口
server.listen(port, () => {
  console.log(`服务运行在端口${port}`)
})

client.on('message', mqtt_messsageReceived)
客户端问题修复

Flutter端socket_io_client默认使用长轮询传输,和服务端默认配置不匹配,且你未主动触发连接操作:

  • 初始化时必须指定transports: ['websocket']参数,强制使用WebSocket协议
  • 初始化完成后调用socket.connect()主动发起连接请求

修正后的Flutter端代码:

import 'package:flutter/material.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
void main() {
  // 补充transports配置,替换成你自己的服务地址
  IO.Socket socket = IO.io('https://xxxx.herokuapp.com/', 
    IO.OptionBuilder()
      .setTransports(['websocket'])
      .disableAutoConnect()
      .build()
  );
  print('mainohhhhh');
  socket.onConnect((data) {
    print('connect');
    socket.emit('msg', 'test');
    print('socketohhhhh');
  });
  socket.on('geocoordinateData', (data) => print(data));
  // 主动发起连接
  socket.connect();
  runApp(const MyApp());
}

// 补充MyApp空实现避免编译报错,你可以保留自己的原有实现
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Scaffold(appBar: AppBar(title: const Text("Socket测试"))));
  }
}
验证步骤
  1. 先启动服务端,确认打印服务运行在端口xxx和MQTT主题订阅成功日志
  2. 启动Flutter客户端,确认服务端打印{socket.id} 已连接日志,同时客户端打印connect日志,证明连接正常
  3. 向你订阅的MQTT主题发送JSON格式消息,确认客户端控制台会打印收到的geocoordinateData事件数据

内容的提问来源于stack exchange,提问作者gbeto Jean-José

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 08:09:00