Flutter for OpenHarmony:shelf_web_socket 快速构建 WebSocket 服务端,实现端到端实时通信(WebSocket 服务器) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:shelf_web_socket 快速构建 WebSocket 服务端,实现端到端实时通信(WebSocket 服务器) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net

在这里插入图片描述

前言

在移动应用开发中,我们通常扮演“客户端”的角色,去连接远程的 WebSocket 服务。但有时,我们需要在设备本身运行一个微型服务器,例如用于局域网内的设备发现、P2P 文件传输信令,或者在调试模式下作为数据广播源。

shelf_web_socket 是基于 Dart 标准 Web 服务器框架 shelf 的 WebSocket 处理器。它能让你在 Flutter 应用(包括 OpenHarmony)中轻松启动一个能够处理 WebSocket 连接的 HTTP 服务。

一、核心概念

  • Shelf: Dart 的 Web 服务器中间件管道框架(类似 Express.js)。
  • Handler: 处理请求并返回响应的函数。
  • WebSocketChannel: 下层封装,让 WebSocket 操作像 Stream 一样简单。

建立连接 ws://ip:port

协议升级请求 (Upgrade Request)

升级成功 (Success)

数据流/接收端 (Stream/Sink)

WebSocket 客户端\n(App/浏览器)

鸿蒙应用\n(shelf_web_socket)

处理器 (shelf handler)

通信通道 (WebSocketChannel)

二、集成与基础用法

2.1 添加依赖

dependencies:shelf: ^1.4.0 shelf_web_socket: ^3.0.0 web_socket_channel: ^3.0.0 

2.2 启动基础服务

import'package:shelf/shelf_io.dart'as shelf_io;import'package:shelf_web_socket/shelf_web_socket.dart';import'package:web_socket_channel/web_socket_channel.dart';voidmain()async{// 定义 WebSocket 处理器var handler =webSocketHandler((WebSocketChannel webSocket){ webSocket.stream.listen((message){print('收到消息: $message'); webSocket.sink.add('服务端已收到: $message');});});// 启动服务,监听所有 IP (0.0.0.0)var server =await shelf_io.serve(handler,'0.0.0.0',8080);print('WebSocket 服务已启动: ws://${server.address.host}:${server.port}');}
在这里插入图片描述

三、进阶场景与示例

3.1 示例一:广播消息

实现一个聊天室功能,将一个客户端发来的消息广播给所有连接者。

import'package:shelf_web_socket/shelf_web_socket.dart';import'package:web_socket_channel/web_socket_channel.dart';finalList<WebSocketChannel> _clients =[];var broadcastHandler =webSocketHandler((WebSocketChannel webSocket){ _clients.add(webSocket);print('新客户端连接,当前在线: ${_clients.length}'); webSocket.stream.listen((message){// 广播给其他客户端for(var client in _clients){if(client != webSocket){ client.sink.add(message);}}}, onDone:(){ _clients.remove(webSocket);print('客户端断开,剩余: ${_clients.length}');});});
在这里插入图片描述

3.2 示例二:鉴权校验

在建立连接前检查 Header 中的 Token。

import'package:shelf/shelf.dart';import'package:shelf_web_socket/shelf_web_socket.dart';HandlerauthMiddleware(Handler innerHandler){return(Request request){if(request.headers['Authorization']!='Bearer my_secret_token'){returnResponse.forbidden('未授权访问');}returninnerHandler(request);};}// 使用 Pipeline 组装// var handler = Pipeline().addMiddleware(authMiddleware).addHandler(wsHandler);
在这里插入图片描述

3.3 示例三:处理二进制数据

WebSocket 不仅能传字符串,还能传字节流(如图片片段)。

import'dart:typed_data';var binaryHandler =webSocketHandler((WebSocketChannel webSocket){ webSocket.stream.listen((message){if(message isList<int>){print('收到二进制数据,长度: ${message.length}');// 处理二进制逻辑...}else{print('收到文本: $message');}});});
在这里插入图片描述

四、OpenHarmony 平台适配

4.1 网络权限

作为服务端,你需要监听端口,这同样需要 Internet 权限。

"requestPermissions":[{"name":"ohos.permission.INTERNET"}]

4.2 后台运行限制

移动操作系统通常限制应用在后台运行服务。如果你的 WebSocket 服务需要长期运行,建议在前台 Service 中启动,或仅在 App 前台可见时运行。

五、完整实战示例:局域网即时画板服务端

本示例将在 OpenHarmony 设备上启动一个 WebSocket 服务。任何连接到该服务的客户端(可以是另一个 App 或浏览器)发送的坐标点,都会被广播给其他人,实现多端协同绘图。

5.1 示例代码

import'dart:async';import'dart:io';import'package:flutter/material.dart';import'package:shelf/shelf_io.dart'as shelf_io;import'package:shelf_web_socket/shelf_web_socket.dart';import'package:web_socket_channel/web_socket_channel.dart';voidmain(){runApp(constMaterialApp(home:ServerPage()));}classServerPageextendsStatefulWidget{constServerPage({super.key});@overrideState<ServerPage>createState()=>_ServerPageState();}class _ServerPageState extendsState<ServerPage>{HttpServer? _server;finalList<WebSocketChannel> _sockets =[];finalList<String> _logs =[];String _ipInfo ='获取中...';@overridevoidinitState(){super.initState();_getIpAddress();}Future<void>_getIpAddress()async{try{final interfaces =awaitNetworkInterface.list(type:InternetAddressType.IPv4);final ip = interfaces.first.addresses.first.address;setState(()=> _ipInfo = ip);}catch(e){setState(()=> _ipInfo ='无法获取 IP');}}// 启动服务Future<void>_startServer()async{var handler =webSocketHandler((WebSocketChannel webSocket){ _sockets.add(webSocket);_log('新连接接入'); webSocket.stream.listen((message){_log('广播数据: $message');// 广播坐标数据for(var socket in _sockets){if(socket != webSocket){ socket.sink.add(message);}}}, onDone:(){ _sockets.remove(webSocket);_log('连接断开');});});try{ _server =await shelf_io.serve(handler,InternetAddress.anyIPv4,8080);_log('服务启动于 ws://$_ipInfo:8080');}catch(e){_log('启动失败: $e');}}Future<void>_stopServer()async{await _server?.close(force:true);for(var s in _sockets){await s.sink.close();} _sockets.clear(); _server =null;_log('服务已停止');}void_log(String msg){if(!mounted)return;setState((){ _logs.insert(0,'[${DateTime.now().hour}:${DateTime.now().minute}] $msg');});}@overridevoiddispose(){_stopServer();super.dispose();}@overrideWidgetbuild(BuildContext context){returnScaffold( appBar:AppBar(title:constText('WebSocket Server')), body:Column( children:[Container( padding:constEdgeInsets.all(20), color:Colors.blue[50], child:Column( children:[Text('本机 IP: $_ipInfo', style:constTextStyle(fontSize:18, fontWeight:FontWeight.bold)),constSizedBox(height:10),Row( mainAxisAlignment:MainAxisAlignment.center, children:[ElevatedButton( onPressed: _server ==null? _startServer :null, child:constText('启动服务'),),constSizedBox(width:20),ElevatedButton( style:ElevatedButton.styleFrom(backgroundColor:Colors.red[100]), onPressed: _server !=null? _stopServer :null, child:constText('停止'),),],),],),),constDivider(),Expanded( child:ListView.builder( itemCount: _logs.length, itemBuilder:(context, index)=>ListTile( leading:constIcon(Icons.info_outline, size:16), title:Text(_logs[index], style:constTextStyle(fontSize:14)),),),),],),);}}
在这里插入图片描述

六、总结

通过 shelf_web_socket,我们让 OpenHarmony 手机不仅仅是信息的消费者,更成为了信息的生产者和中转站。

最佳实践

  1. 异常处理:Websocket 连接很容易因网络波动断开,务必处理 onDoneonError
  2. 资源释放:在组件销毁或应用退出时,务必关闭 Server 和所有 Channel连接,防止端口占用。
  3. 心跳机制:为了保持连接活性,建议在应用层实现 Ping/Pong 心跳包。

Read more

ChatALL终极指南:一键同时对话40+AI大模型的免费神器

ChatALL终极指南:一键同时对话40+AI大模型的免费神器 【免费下载链接】ChatALL Concurrently chat with ChatGPT, Bing Chat, Bard, Alpaca, Vicuna, Claude, ChatGLM, MOSS, 讯飞星火, 文心一言 and more, discover the best answers 项目地址: https://gitcode.com/gh_mirrors/ch/ChatALL 还在为选择哪个AI助手而烦恼吗?ChatALL让你无需纠结,一次性与ChatGPT、Claude、文心一言、讯飞星火等40多个主流AI模型同时对话,快速获取最优解决方案。这款开源工具彻底改变了人与AI的交互方式,让AI协作变得前所未有的简单高效。 🚀 为什么你需要ChatALL? 想象一下这样的场景:当你需要编写一段代码时,可以同时让GPT-4o提供创意实现、Claude 3进行逻辑检查、CodeLlama优化性能——所有这一切在3分钟内完成,

【人工智能】全网都在学的 OpenClaw 保姆级指南:重点全整理好了!

【人工智能】全网都在学的 OpenClaw 保姆级指南:重点全整理好了!

一、OpenClaw 到底火在哪? OpenClaw(小龙虾)最近在 AI 圈刷屏恭喜OpenClaw 登顶 Github 历史 Star 榜首!,原因很简单——它是目前少数几个真正能帮你动手干活的 AI 助理。 具体能干什么: * 自动操作浏览器:登网站、填表单、截图、抓数据,网页上能干的,它全干 * 控制你的电脑:装软件、写代码、跑程序、监控任务,鼠标键盘它都能接管 * 24 小时不间断运行:你甩给它一个任务,它自己拼命搞定,完事等你验收 * 越用越懂你:向量记忆模块,用的次数越多,它越知道你的习惯和偏好 说了这么多,不如直接上手——下面我把从零到跑起来的全流程,一次给你整明白。 二、动手之前,先搞懂这两件事 很多人直接扑上去装,装完一头雾水,搞不清楚为什么跑不起来。

合合信息AI 鉴伪检测技术,揪出 “难察觉” 的虚假源头

合合信息AI 鉴伪检测技术,揪出 “难察觉” 的虚假源头

文章目录 * 一、前言 * 二、AI鉴伪技术构建安全可信的防线 * 2.1 人脸视频篡改检测 * 2.2 AIGC图像鉴别技术 * 2.3 TextIn通用篡改检测平台 * 三、总结 一、前言 随着人工智能技术与PS等图像伪造技术的深度融合与高速迭代,AI技术目前已迈入高度发展阶段。AI 生成内容(AIGC)技术凭借其强大的学习能力和创作能力,能在短时间内生成足以乱真的文本、图像、音频乃至视频。 然而,技术的进步是一把双刃剑。在生成合成内容质量实现显著提升,甚至达到以假乱真境界的当下,其带来的安全隐患也日益凸显,且呈现出激增态势。借助先进的 AI 技术,不法分子能够轻易将一个人的面部特征移植到另一个人的视频或图像中,制作出极其逼真的虚假内容。 这种技术滥用的情况已经渗透到多个领域,给信息安全、社会信任等诸多方面带来了严峻挑战。人脸视频、AIGC生成图像以及证件票据等领域,已然成为AI伪造的“重灾区”。人脸视频伪造可能会被不法分子用于制造虚假新闻等恶意行为;AIGC生成图像的泛滥,使得真实与虚假信息难以分辨;而证件票据的伪造更是直接关系到经济安全和

【全网最全横评】8家大厂8只AI龙虾Agent实测对比:OpenClaw、AutoClaw、KimiClaw、QClaw谁才是最优解?

【全网最全横评】8家大厂8只AI龙虾Agent实测对比:OpenClaw、AutoClaw、KimiClaw、QClaw谁才是最优解?

**摘要:**8 家大厂先后推出了自己的「龙虾」(AI Agent),从开源免费到 ¥199/月,从本地部署到纯云端,到底哪个最适合你?本文以腾讯 10+ 年程序员视角,逐一实测 OpenClaw、AutoClaw、KimiClaw、MaxClaw、CoPaw、ArkClaw、QClaw+WorkBuddy、miclaw,给出完整横评数据和场景化选型建议。 目录 * 前言 * 一、为什么突然冒出这么多「龙虾」? * 1.1 龙虾是什么? * 1.2 大厂为什么扎堆入场? * 二、8 只龙虾逐一实测 * 2.1 OpenClaw(开源原版) * 2.2 智谱 AutoClaw(澳龙) * 2.3