Flutter Web使用dartssh2连接SFTP报错:Native socket不支持Web环境
Flutter Web使用dartssh2连接SFTP报错问题解决
问题说明
开发Flutter Web应用(Chrome调试)时,通过SFTP从主机拉取文件,执行final socket = await SSHSocket.connect(<url>, <port>);语句失败。已尝试多个SFTP相关包,当前使用dartssh2(官方说明支持Web环境),但连接始终出错。
核心代码结构(globals.dart):
//////globals.dart 76 Future<void> getStatsContent() async { 78 final socket = await SSHSocket.connect(<url>, <port>); 79 81 final client = SSHClient( 82 socket, 83 username: <username>, 84 onPasswordRequest: () => <password>, 85 ); 86 89 final sftp = await client.sftp(); 90 final file = await sftp.open('stats.json'); 91 94 final content = await file.readBytes(); 95 98 statsContent = json.decode(latin1.decode(content)); 99 102 client.close(); 103 await client.done; 104 }
终端报错信息
dart_sdk.js:5397 Uncaught (in promise) Error: UnimplementedError: Native socket is not supported on web at Object.throw_ [as throw] (dart_sdk.js:5397:11) at connectNativeSocket (ssh_socket_js.dart.lib.js:22:17) at connectNativeSocket.next (<anonymous>) at runBody (dart_sdk.js:40710:34) at Object._async [as async] (dart_sdk.js:40742:7) at Object.connectNativeSocket (ssh_socket_js.dart.lib.js:21:18) at connect (ssh_socket_js.dart.lib.js:29:36) at connect.next (<anonymous>) at runBody (dart_sdk.js:40710:34) at Object._async [as async] (dart_sdk.js:40742:7) at SSHSocket.connect (ssh_socket_js.dart.lib.js:28:20) at getStatsContent (globals.dart:78:34) at getStatsContent.next (<anonymous>) at runBody (dart_sdk.js:40710:34) at Object._async [as async] (dart_sdk.js:40742:7) at Object.getStatsContent (globals.dart:76:29) at guildselect.dart:250:51 at Generator.next (<anonymous>) at runBody (dart_sdk.js:40710:34) at Object._async [as async] (dart_sdk.js:40742:7) at guildselect.dart:247:52 at ink_well._InkResponseState.new.handleTap (back_button.dart.lib.js:61234:31) at tap.TapGestureRecognizer.new.invokeCallback (recognizer.dart.lib.js:222:18) at tap.TapGestureRecognizer.new.handleTapUp (tap.dart.lib.js:433:20) at [_checkUp] (tap.dart.lib.js:224:12) at tap.TapGestureRecognizer.new.handlePrimaryPointer (tap.dart.lib.js:171:23) at tap.TapGestureRecognizer.new.handleEvent (recognizer.dart.lib.js:485:16) at [_dispatch] (pointer_router.dart.lib.js:93:9) at pointer_router.dart.lib.js:119:26 at LinkedMap.new.forEach (dart_sdk.js:28056:11) at [_dispatchEventToRoutes] (pointer_router.dart.lib.js:117:29) at pointer_router.PointerRouter.new.route (pointer_router.dart.lib.js:112:37) at binding$5.WidgetsFlutterBinding.new.handleEvent (binding.dart.lib.js:381:26) at binding$5.WidgetsFlutterBinding.new.dispatchEvent (binding.dart.lib.js:369:24) at binding$5.WidgetsFlutterBinding.new.dispatchEvent (view.dart.lib.js:699:13) at [_handlePointerEventImmediately] (binding.dart.lib.js:345:14) at binding$5.WidgetsFlutterBinding.new.handlePointerEvent (binding.dart.lib.js:315:43) at [_flushPointerEventQueue] (binding.dart.lib.js:304:14) at [_handlePointerDataPacket] (binding.dart.lib.js:292:38) at Object.invoke1 (dart_sdk.js:200378:7) at _engine.EnginePlatformDispatcher.new.invokeOnPointerDataPacket (dart_sdk.js:175073:15) at [_onPointerData] (dart_sdk.js:176047:49) at dart_sdk.js:176592:30 at dart_sdk.js:176532:9 at loggedHandler (dart_sdk.js:176223:11) at dart_sdk.js:176141:78 at Object._checkAndCall (dart_sdk.js:5600:16) at Object.dcall (dart_sdk.js:5605:17) at ret (dart_sdk.js:62582:21)
Flutter Doctor检查结果
[√] Flutter (Channel stable, 3.7.5, on Microsoft Windows [Version 10.0.19044.2604], locale en-US) [√] Windows Version (Installed version of Windows is version 10 or higher) [√] Android toolchain - develop for Android devices (Android SDK version 33.0.0) [√] Chrome - develop for the web [√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.3.1) [√] Android Studio (version 2021.2) [√] Connected device (3 available) [√] HTTP Host Availability
解决方法
Web环境不支持原生Socket连接,dartssh2在Web端需使用WebSocket替代普通Socket,具体操作如下:
- 服务器配置:确保服务器支持SSH over WebSocket,若不支持,需通过反向代理(如Nginx)将WebSocket请求转发到SSH服务端口。
- 代码修改:替换
SSHSocket.connect为WebSocket连接,再包装为SSHSocket:
// 替换原SSHSocket.connect语句 final webSocket = await WebSocket.connect('wss://<你的服务器地址>/ssh'); final socket = SSHSocket.fromWebSocket(webSocket); // 后续客户端初始化及SFTP操作代码保持不变 final client = SSHClient( socket, username: <username>, onPasswordRequest: () => <password>, ); final sftp = await client.sftp(); // ... 其余代码
若无法修改服务器配置,可搭建中间API服务,由后端处理SFTP请求,Flutter Web通过HTTP接口获取文件内容。
内容的提问来源于stack exchange,提问作者user18797867
相关产品推荐
相关产品推荐

