Flutter文件共享服务插件samba_server的使用
Flutter 文件共享服务插件 samba_server 的使用
快速开始
以下是一个简单的示例,展示了如何使用 samba_server
插件来创建一个简单的 HTTP 服务器,并处理一些基本请求。
import 'dart:async';
import 'package:samba_server/samba_server.dart';
// 定义一个简单的 GET 路由
class HelloRoute extends Route {
HelloRoute() : super(HttpMethod.get, '/');
@override
FutureOr<Response> handler(Request request) {
return Response.ok(body: 'Hello from SAMBA_SERVER');
}
}
// 定义一个 WebSocket 路由
class ChatSocketRoute extends WebSocketRoute {
@override
FutureOr<void> onConnected(WebSocket webSocket) {
// 当客户端连接时触发
webSocket.emit('message', {'connectionStatus': 'successful'});
// 监听来自客户端的消息
webSocket.on('message', (data) {
print('Received message: $data');
});
}
}
Future<void> main() async {
final httpServer = HttpServer();
// 注册路由
httpServer
..registerRoute(HelloRoute())
..registerRoute(ChatSocketRoute());
// 绑定服务器地址和端口
await httpServer.bind(address: '127.0.0.1', port: 8080);
}
特性
- 高性能:
samba_server
是一个为 API 和事件驱动的 WebSocket 开发而设计的高效后端开发框架。 - 基于 Radix Trie 的健壮路由系统。
- 支持事件驱动的 WebSocket 与房间功能。
- 可以拦截任何请求或响应进行预处理或后处理。
- 优雅的错误处理。
- 高覆盖率的测试。
安装
- 确保已经安装了 Dart SDK 3.0.0 或更高版本。
- 使用
dart pub add samba_server
命令将samba_server
添加到你的项目中。
运行测试
为了运行测试套件,首先需要安装依赖项,然后运行测试套件。注意 -j 1
是必需的参数,以防止所有测试并行运行导致某些测试失败。
dart pub get
dart test -j 1
作者
Samba Server
的原始作者和主要维护者是 @tejHackerDev。
请求
请求类是 HttpRequest
类的一个包装器,包含有关传入服务器请求的信息。
路径参数
路径参数是一个 Map<String, String>
,其中键是动态路径参数的名称,值是在运行时传递的值。
查询参数
查询参数是一个 Map<String, dynamic>
,其中键是请求中传递的名称,值是相应键传递的数据。
请求头
请求头是一个 Map<String, String>
,其中键是头部名称,值是该名称传递的数据。如果为同一键传递多个值,则它们将用逗号连接。
请求体
请求体是一个 dynamic
类型,默认情况下如果没有传递请求体则为 null
。如果传递了请求体,则默认类型为 Stream<Uint8List>
,除非通过任何请求解码器转换。
请求解码器
请求解码器是一个自定义拦截器类,可以根据请求头中的 content-type
对请求体进行解码。默认情况下,Samba Server
提供了一些内置的请求解码器,例如 StringRequestDecoder
、FormUrlencodedRequestDecoder
、JsonRequestDecoder
和 MultipartRequestDecoder
。
响应
响应类是 HttpResponse
类的一个包装器,包含有关传出数据的信息。
响应头
响应头是一个 Map<String, String>
,其中键是头部名称,值是该名称传递的数据。
响应体
响应体是一个 Object?
类型,默认情况下如果没有传递响应体则为 null
。
响应编码器
响应编码器是一个自定义拦截器类,可以根据值的类型对响应体进行编码。默认情况下,Samba Server
提供了一些内置的响应编码器,例如 StringResponseDecoder
、NumResponseDecoder
、BoolResponseDecoder
、JsonListResponseDecoder
和 JsonMapResponseDecoder
。
路由
要为 HTTP 服务器创建路由,需要扩展 Route
类,并将其注册到服务器上。还应指定 HTTP 方法和路径作为匹配标准。
静态路由
静态路由是不包含任何动态参数的路由。
class GetUsersRoute extends Route {
GetUsersRoute() : super(HttpMethod.get, '/users');
@override
FutureOr<Response> handler(Request request) {
return Response.ok(body: 'Users');
}
}
参数化路由
参数化路由包含一些在路径中的动态路径参数。
非正则表达式路由
非正则表达式路由不包含任何正则表达式在动态路径参数中。
class GetUserRoute extends Route {
GetUserRoute() : super(HttpMethod.get, '/users/{id}');
@override
FutureOr<Response> handler(Request request) {
final userId = request.pathParameters['id'];
return Response.ok(body: userId);
}
}
正则表达式路由
正则表达式路由包含一个在动态路径参数中的正则表达式,该正则表达式由冒号 :
分隔。
class GetUserRoute extends Route {
GetUserRoute() : super(HttpMethod.get, '/users/{id:^[a-z]+\$}');
@override
FutureOr<Response> handler(Request request) {
final userId = request.pathParameters['id'];
return Response.ok(body: userId);
}
}
通配符路由
通配符路由以 *
结束路径。
class UsersWildcardRoute extends Route {
UsersWildcardRoute() : super(HttpMethod.get, '/users/*');
@override
FutureOr<Response> handler(Request request) {
final remainingPath = request.pathParameters['*'];
return Response.ok(body: 'Remaining path $remainingPath');
}
}
WebSocket
WebSocket 是一种用于实现在客户端和服务器之间双向通信的协议。
WebSocket 路由
WebSocket 路由是 Route
类的扩展版本,用于处理 WebSocket 连接。
class ChatSocketRoute extends WebSocketRoute {
@override
FutureOr<void> onConnected(WebSocket webSocket) {
// 发送连接成功的消息给客户端
webSocket.emit(
'message',
{
'connectionStatus': 'successful',
},
);
// 监听客户端发送的消息
webSocket.on('message', (data) {
print('Received message: $data');
});
}
}
房间
房间是服务器端的概念,客户端无法控制。服务器可以通过调用 join
函数添加客户端到房间,通过调用 leave
函数移除客户端从房间。
class ChatSocketRoute extends WebSocketRoute {
@override
FutureOr<void> onConnected(WebSocket webSocket) {
// 将客户端加入名为 `discussions` 的房间
webSocket.join('discussions');
// 向所有在房间中的客户端发送消息
emit(
'message',
{
'connectedUserId': webSocket.id,
},
rooms: ['discussions'],
);
// 移除客户端从名为 `discussions` 的房间
webSocket.leave('discussions');
}
}
拦截器
拦截器是一种可以在请求或响应之前或之后修改的类。它可以帮助在返回响应之前阻止进一步的拦截器或路由。
class LoggerInterceptor extends Interceptor {
@override
FutureOr<Response?> onInit(Request request) {
// 当拦截器进入执行范围时触发
return super.onInit(request);
}
@override
FutureOr<Response> onDispose(Request request, Response response) {
// 当拦截器退出执行范围时触发
return super.onDispose(request, response);
}
}
错误处理
任何在处理请求时发生的错误都会被捕获并传递给 errorHandler
。
Future<void> main() async {
final httpServer = HttpServer();
httpServer.registerErrorHandler((request, response, error, stackTrace) {
return Response.internalServerError(body: 'Some error has occurred');
});
await httpServer.bind(address: '127.0.0.1', port: 8080);
}
关闭服务器
可以通过调用服务器的 shutdown
函数来停止服务器。默认情况下,服务器会优雅地关闭,等待任何未完成的请求完成。如果不希望这种行为,可以将 gracefully
参数设置为 false
。
Future<void> main() async {
final httpServer = HttpServer();
await httpServer.bind(address: '127.0.0.1', port: 8080);
// 根据适当的条件终止服务器
if (true) {
await httpServer.shutdown();
}
}
更多关于Flutter文件共享服务插件samba_server的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文件共享服务插件samba_server的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用samba_server
插件来创建文件共享服务的示例代码。请注意,这个插件可能需要在你的设备上具备特定的权限和网络配置,以确保Samba服务能够正常运行。
首先,确保你已经在pubspec.yaml
文件中添加了samba_server
依赖:
dependencies:
flutter:
sdk: flutter
samba_server: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在Flutter应用中配置和使用Samba服务。以下是一个基本的示例,展示了如何启动一个Samba服务并共享一个本地目录:
import 'package:flutter/material.dart';
import 'package:samba_server/samba_server.dart';
import 'dart:io';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
SambaServer? _sambaServer;
String _status = "Service not started";
@override
void initState() {
super.initState();
_startSambaServer();
}
@override
void dispose() {
_stopSambaServer();
super.dispose();
}
Future<void> _startSambaServer() async {
Directory sharedDir = Directory('/path/to/shared/directory'); // 替换为你想共享的目录路径
_sambaServer = SambaServer(
sharedDir: sharedDir,
username: 'guest',
password: 'guest', // 这里设置了一个简单的用户名和密码,实际使用中应该更加安全
workgroupName: 'WORKGROUP',
serverName: 'MyFlutterSambaServer',
);
try {
await _sambaServer!.start();
setState(() {
_status = "Service started successfully";
});
} catch (e) {
setState(() {
_status = "Failed to start service: $e";
});
}
}
Future<void> _stopSambaServer() async {
if (_sambaServer != null) {
await _sambaServer!.stop();
setState(() {
_status = "Service stopped";
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Samba Server Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Samba Server Status: $_status',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
if (_sambaServer!.isRunning) {
await _stopSambaServer();
} else {
await _startSambaServer();
}
},
child: Text(_sambaServer?.isRunning == true ? 'Stop Server' : 'Start Server'),
),
],
),
),
),
);
}
}
注意事项:
- 权限:确保你的应用具有访问和共享指定目录的权限。在Android上,你可能需要在
AndroidManifest.xml
中请求特定的存储权限。 - 网络配置:确保你的设备在同一个网络上,并且防火墙或路由器设置不会阻止Samba服务的端口(通常是137, 138, 139, 和445)。
- 安全性:上面的示例中使用了简单的用户名和密码(‘guest’),在实际应用中应该使用更安全的认证机制。
- 插件版本:
samba_server
插件的API可能会随着版本更新而变化,请参考最新的插件文档进行调整。
这个示例提供了一个基本的框架,你可以根据实际需求进行扩展和修改。