- Published on
localsend源码学习(一) - 介绍
- Authors
- Name
- realth000
介绍
localsend是一款开源的跨平台局域网文件/消息投送软件,只要在连上相同WIFI的设备上开启localsend客户端,即可方便地在设备间传送文件,具有以下特点:
- 跨平台,支持Windows,Linux,Android等平台。
- 支持HTTPS,端到端加密。
- 不需要连接到互联或第三方服务器,P2P的文件/消息传送。
正好满足我的需要,而且是Flutter编写的,自然有兴趣学习一下。
实际上本来正在拿flutter写一个很类似的软件呢,写了一半发现人家的好用就直接用上了。
项目组成
按照README中的提示,克隆git repo后通过flutter pub run build_runner build -d
生成代码,然后开始阅读项目。
✿ tree -d lib
lib
├── gen
├── model
│ ├── dto
│ ├── send
│ └── server
├── pages
│ ├── debug
│ └── tabs
├── provider
│ ├── network
│ └── selection
├── util
└── widget
├── animations
├── dialogs
├── list_tile
└── watcher
17 directories
✿ find lib -name "*.dart" 2>/dev/null | xargs wc -l | tail -n 1
22971 总用量
目录数量还好,总代码量(算上生成的)不到两万三千行,flutter的行数嘛懂得都懂,不算太多。
✿ cat pubspec.yaml
...
dependencies:
basic_utils: 5.4.2
collection: 1.17.0
connectivity_plus: 3.0.3
desktop_drop: 0.4.0
device_info_plus: 8.1.0
dio: 4.0.6
file_picker: 5.2.5
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
flutter_markdown: 0.6.13
flutter_riverpod: 2.1.3
freezed_annotation: 2.2.0
image_gallery_saver: 1.7.1
image_picker: 0.8.6
intl: 0.17.0
json_annotation: 4.7.0
launch_at_startup: 0.2.1
network_info_plus: 3.0.2
open_filex: 4.3.2
package_info_plus: 3.0.3
path_provider: 2.0.11
permission_handler: 10.2.0
routerino: 0.3.0
screen_retriever: 0.1.6
share_handler: 0.0.16
shared_preferences: 2.0.17
shelf: 1.4.0
shelf_router: 1.1.3
slang: 3.12.0
slang_flutter: 3.12.0
tray_manager:
# https://github.com/leanflutter/tray_manager/issues/30
# The Linux tray manager is disabled for now
git:
url: https://github.com/Tienisto/tray_manager.git
ref: b37f5e088e0f02c45a684ae41e9d2da2d5c596db
url_launcher: 6.1.9
uuid: 3.0.7
wakelock: 0.6.2
wechat_assets_picker: 8.3.2
window_manager: 0.2.8
dev_dependencies:
build_runner: 2.3.3
flutter_gen_runner: 5.1.0+1
flutter_lints: 2.0.1
freezed: 2.3.2
json_serializable: 6.5.4
msix:
# https://github.com/YehudaKremer/msix/pull/174
git:
url: https://github.com/Tienisto/msix.git
ref: 207eddfe797225ab2736001cbdb8fafd04946b38
slang_build_runner: 3.12.0
test: 1.22.1
dependency_overrides:
share_handler_platform_interface:
# https://github.com/ShoutSocial/share_handler/pull/39
# Remove this when next release is published
git:
url: https://github.com/ShoutSocial/share_handler.git
path: share_handler_platform_interface
ref: 630cf945524dfbae1bc63ed83b28559b47b25ffa
# cannot open windows settings in 3.0.3
url_launcher_windows: 3.0.2
...
依赖的包不少,重要的包分下类:
- 状态管理:flutter_riverpod
- 路由管理:routerino
- 网络服务:dio, shelf
- 国际化:slang
- 代码生成:freezed, build_runner
代码生成用的两个包比较陌生,之前没用过代码生成,本系列重点学习一下。riverpod刚接触过,思想和用法还不顺手,dio之前用过,shelf之前用的时候觉得不好用,用go做了个服务器当替代方案,国际化的slang没用过,整个学下来能收获不少呀。
依赖介绍
- riverpod:一个状态管理包,在能方便地access状态的同时保证好写测试,算provider的升级版,同一个作者开发。半个老朋友,前段时间刚从getx切到riverpod,各种概念比较迷糊,用起来也不熟练。从这个项目看来riverpod的流行度也不算低啊。比较好奇的是,竟然用的是flutter_riverpod而不是hook_riverpod,难道没有在
widget
之外用过state吗?虽然之前文章说了选flutter_riverpod,但是用的时候如果脱离了flutter那一套(即没有ref),那么再使用state的时候需要用ProviderContainer
,留个意看看localsend如何做到的。 - routerino:官方介绍:在声明对应关系且不适用build_runner的情况下使用命名路由。目前没看出和go_router或者getx相比有什么优势,以后仔细看看。
- dio:http client包,同类型中使用最广泛的。之前写类似软件的时候用了,简单好用。
- shelf:http server包,dart目前偏向客户端,像shelf这样用于服务端的包比较少,shelf是其中使用较多的。之前也考虑过直接拿dart写http服务器,后来觉得不够靠谱就拿go做了server。
- freezed:依靠代码生成,简单地制作出“数据类”,kotlin里好像有这个概念,data class,这个类就是个数据组合,类似结构体。freezed提供了
toString()
、==
、hashCode()
的重载,并且提供copyWith
方法,且可支持序列化/反序列化,功能挺强的。 - build_runner:flutter官方推出的代码生成工具,很多包都依赖它。
功能介绍
localsend提供了哪些功能呢?
- 局域网文件/消息发送。
- 局域网内设备发现,默认每个客户端提供一个ID用于识别,也可以手动指定IP。
- 默认状态下接收端收文件需要点确定,也提供不需要确定的快速下载模式供服务端场景使用。
- 可以更改下载目录,有下载历史。
- 默认开启SSL,可以关闭。
- 有托盘图标,可以驻留后台。
- 支持开机自启。
- 支持更换端口。
- 支持多种语言。
基本上和我想做的局域网流转软件一模一样,我放弃我自己做那个了,正好通过localsend学习flutter,只会getx那一套并不行,很多包使用的时候需要statefulwidget,这种场景和getx并不契合。
这篇文章稍微水了点,主要介绍一下localsend,下一期从具体角度分析下localsend的源码。
本来早就想写,这一周因为某些奇怪的无可奈何的原因没弄成,还过得很不舒坦,今天算好了一些,希望今后不再出这种问题吧。