基于Flutter开发LAN手游:Socket.io客户端与服务端一体化方案咨询
方案建议与入门指引
可行方案
1. 使用官方Dart Socket.io服务端库
试试socket_io_server——这是官方适配Dart的Socket.io服务端库,直接集成在Flutter项目里,不需要跨语言打包,完全匹配你的局域网低延迟、广播需求。
2. 原生Dart UDP/TCP替代
如果Socket.io服务端实现有门槛,推荐用Dart自带的socket库做UDP通信。UDP天生适合局域网低延迟场景,无需握手,广播实现简单,代码量少,对新手友好。
3. 嵌入轻量Node.js服务端
若你更熟悉JS的Socket.io服务端写法,可以把Node.js服务打包成二进制,在Flutter中通过Process启动。Android端可将Node二进制放在assets目录,运行时复制到可执行目录再启动,适配成本不高。
入门实操指引
方案1:Socket.io服务端+客户端实现
步骤1:添加依赖
在pubspec.yaml中添加:
dependencies: socket_io_client: ^2.0.0 socket_io_server: ^1.0.1
执行flutter pub get安装依赖。
步骤2:主机模式(启动服务端)
在Flutter代码中直接启动Socket.io服务,监听局域网端口:
import 'package:socket_io_server/socket_io_server.dart'; void startGameHost() { // 启动服务,监听所有局域网接口的3000端口 final io = Server(); io.listen(3000); // 处理客户端连接 io.on('connection', (client) { print('玩家 ${client.id} 已加入'); // 接收玩家输入,广播给其他所有玩家 client.on('player_action', (data) { client.broadcast.emit('game_state_update', data); }); // 处理断开连接 client.on('disconnect', (_) => print('玩家 ${client.id} 已离开')); }); }
步骤3:玩家模式(连接服务端)
连接到主机的Socket.io服务:
import 'package:socket_io_client/socket_io_client.dart' as io; void connectToHost(String hostIp) { final socket = io.io('http://$hostIp:3000', { 'transports': ['websocket'], // 优先用WebSocket降低延迟 'autoConnect': false, }); socket.connect(); socket.onConnect((_) { print('成功连接到主机'); // 发送玩家操作 socket.emit('player_action', {'playerId': 'my_id', 'action': 'jump'}); }); // 接收主机广播的游戏状态 socket.on('game_state_update', (data) { // 更新本地游戏UI或状态 print('收到游戏更新:$data'); }); socket.onDisconnect((_) => print('与主机断开连接')); }
步骤4:获取主机局域网IP
让其他玩家找到主机,需要获取主机的局域网IP:
import 'dart:io'; Future<String?> getLocalLanIp() async { for (final interface in await NetworkInterface.list()) { for (final addr in interface.addresses) { if (addr.type == InternetAddressType.IPv4 && !addr.isLoopback) { return addr.address; } } } return null; }
方案2:原生UDP广播实现(更简单)
主机端(发送广播)
import 'dart:io'; void startUdpHost() async { final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 4000); socket.listen((event) { if (event == RawSocketEvent.read) { final datagram = socket.receive(); if (datagram != null) { final msg = String.fromCharCodes(datagram.data); print('收到玩家消息:$msg'); // 向整个局域网广播游戏状态 socket.send( '游戏状态更新'.codeUnits, InternetAddress('255.255.255.255'), // 局域网广播地址 4001, ); } } }); }
玩家端(接收广播)
import 'dart:io'; void startUdpPlayer() async { final socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 4001); socket.listen((event) { if (event == RawSocketEvent.read) { final datagram = socket.receive(); if (datagram != null) { final msg = String.fromCharCodes(datagram.data); print('收到主机广播:$msg'); // 更新本地游戏状态 } } }); }
内容的提问来源于stack exchange,提问作者asimtot
相关产品推荐
相关产品推荐

