PeerClip · 跨设备剪贴板同步
一次部署,多端通用。把你的 PC、Mac、iPhone、Android、平板都拉进同一个「房间」,随手粘贴文本、图片和文件。
项目介绍
PeerClip 是一个面向多设备场景的临时文件与剪贴板传输工具。
它不需要安装原生客户端,只需要打开浏览器,就可以把 PC、Mac、iPhone、Android、平板 等设备加入同一个房间,在设备之间快速同步文本、图片以及文件。
项目采用「房间 + 设备审批」的机制管理访问权限,并通过二维码降低移动端加入房间的操作成本。文本消息通过 Redis 持久化,图片和文件则使用 Cloudflare R2 存储,并通过预签名 URL 实现浏览器直传。
✨ 核心特性
🔗 房间机制
首次打开 PeerClip 时会自动生成唯一的房间 ID,并通过 URL 中的 ?room=xxx 标识当前房间。
只需要分享房间链接,或者让其他设备扫描页面上的二维码,就可以快速加入同一个空间。
📱 二维码快速加入
页面内置房间二维码。
手机或平板无需手动输入房间号,直接扫码即可进入当前房间,非常适合电脑与手机之间临时传输内容。
🔐 设备审批
为了避免房间链接被误分享后产生陌生设备加入,PeerClip 引入了设备审批机制。
- 第一个进入房间的设备自动成为管理员
- 后续设备默认处于
pending状态 - 管理员可以选择
Approve或Reject - 只有通过审批的设备才能查看和发送房间内容
在保持使用简单的同时,也增加了一层基础的访问控制。
📝 文本即时同步
在任意设备输入或粘贴文本,发送后其他已批准设备即可看到消息。
同时提供一键复制按钮,可以直接把内容复制回当前设备的系统剪贴板。
对于临时传输:
一段代码、一条命令、一个链接、一段配置,都可以直接丢进房间。
🖼️ 多图片传输
支持一次选择多张图片,并以卡片轮播的形式展示。
移动端还针对图片预览增加了触控操作:
- 双击放大 / 还原
- 单指拖动图片
- 双指捏合缩放
- 全屏查看
对于电脑截图后传到手机这样的场景尤其方便。
📎 通用文件上传
除了图片之外,也支持其他类型的文件,例如:
- 压缩包
- PDF / 文档
- 视频
- 代码文件
- 其他常见文件
文件会以卡片形式展示,并提供文件类型、大小以及下载操作。
☁️ Cloudflare R2 预签名直传
图片和文件并不会先经过 Next.js Serverless Function,而是采用:
浏览器
↓
请求上传地址
↓
Next.js / Vercel 生成 Presigned URL
↓
浏览器直接 PUT
↓
Cloudflare R2
这种方式可以避免文件上传经过服务端中转,同时不会把 R2 的 Access Key 暴露给前端。
项目目前对图片和文件大小进行了限制:
- 图片:≤ 10 MB
- 文件:≤ 50 MB
⚡ 乐观更新 + 轮询
PeerClip 没有采用复杂的 WebSocket 架构,而是使用轮询获取最新消息。
为了避免发送消息后出现:
发送 → 消失 → 重新出现
的视觉跳动,前端使用了乐观更新 + 按 ID 合并轮询结果的方式。
用户发送消息后立即将其显示在界面中,后台轮询到服务端数据后再进行合并。
同时,轮询过程中会比较消息 ID 列表和长度。如果数据没有变化,就跳过 setState,减少不必要的渲染。
🤖 在线设备管理
设备会定期发送心跳。
如果设备超过一定时间没有心跳,系统会自动将其清理,避免设备列表长期残留已经离线的设备。
💾 Redis 持久化
房间、设备以及消息数据都存储在 Redis 中。
因此即使部署在 Vercel Serverless 环境下,也不会因为函数冷启动或实例变化导致数据完全丢失。
🛠 技术栈
| 层级 | 技术 | 用途 |
|---|---|---|
| Framework | Next.js 16 | App Router、页面与 API |
| UI | React 19 | 前端交互与组件 |
| Styling | Tailwind CSS 4 | 原子化 CSS |
| Language | TypeScript 5 | 类型安全 |
| Icons | lucide-react | SVG 图标 |
| QR Code | qrcode.react | 房间二维码 |
| Database | Redis / ioredis | 房间、设备、消息持久化 |
| File Storage | Cloudflare R2 | 图片与文件存储 |
| Upload | Presigned URL | 浏览器直传 R2 |
| Deployment | Vercel | Serverless 部署 |
项目实际采用 Next.js + React + Tailwind CSS + TypeScript 构建,Redis 用于会话与消息数据存储,Cloudflare R2 用于图片及文件存储,整体针对 Vercel Serverless 环境进行了适配。
🚀 使用方式
1. 创建房间
打开 PeerClip 后,系统会自动创建一个房间。
第一个进入房间的设备会自动成为管理员。
2. 添加其他设备
可以直接复制当前房间 URL,也可以使用页面中的二维码。
在手机上扫码后即可快速进入房间。
3. 审批设备
新设备进入后默认处于 pending 状态。
管理员在设备列表中点击 Approve,设备即可正式加入房间。
4. 开始传输
之后就可以直接:
- 粘贴文本
- 粘贴截图
- 选择图片
- 上传文件
- 一键复制文本
- 下载其他设备发送的文件
整个过程不需要安装额外客户端。
🏗️ 项目结构
peerclip/
├─ app/
│ ├─ page.tsx
│ ├─ layout.tsx
│ ├─ globals.css
│ └─ api/
│ ├─ clipboard/
│ │ └─ route.ts
│ └─ upload/
│ └─ route.ts
├─ public/
│ └─ logo.jpg
├─ .env.example
├─ next.config.ts
├─ postcss.config.mjs
├─ eslint.config.mjs
├─ tsconfig.json
├─ package.json
└─ README.md
其中核心逻辑主要集中在两个 API:
clipboard/route.ts:负责消息轮询、设备心跳、消息发送以及设备审批upload/route.ts:负责生成 Cloudflare R2 预签名上传 URL
前端 page.tsx 则负责页面 UI、轮询、消息合并、文件上传以及图片手势交互。
🔧 本地运行
项目需要 Node.js 20+,同时需要准备一个可访问的 Redis 和 Cloudflare R2 Bucket。
git clone https://github.com/Licy711/lan-clipboard.git
cd lan-clipboard
npm install
cp .env.example .env.local
npm run dev
然后访问:
http://localhost:3000
首次打开后会自动生成房间,使用手机扫描页面上的二维码即可测试跨设备同步。
生产环境可以使用:
npm run build
npm start
🔐 环境变量
PeerClip 需要配置 Redis 和 Cloudflare R2 相关环境变量:
REDIS_URL=
R2_ACCOUNT_ID=
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_BUCKET=
R2_PUBLIC_DOMAIN=
其中 R2 API Token 建议遵循最小权限原则,只授予目标 Bucket 的 Object Read & Write 权限,而不是整个 Cloudflare Account 的管理权限。
☁️ 为什么选择 R2 直传?
如果直接让浏览器把文件上传到 Next.js API,再由服务端转发到对象存储,就会让 Serverless Function 成为文件传输的中间层。
PeerClip 采用 Presigned URL 后,流程变成:
Client
│
│ 请求上传 URL
▼
Next.js API
│
│ 生成 Presigned PUT URL
▼
Client
│
│ 直接上传
▼
Cloudflare R2
这样既减少了服务器的数据传输压力,也避免了将 R2 密钥发送到浏览器端。
同时也可以绕过 Vercel Serverless Function 的请求体限制。
🌐 部署
项目针对 Vercel Serverless 环境进行了优化,因此可以直接导入 GitHub 仓库进行部署。
基本流程:
GitHub
↓
Vercel Import
↓
配置 Redis
↓
配置 Cloudflare R2
↓
Deploy
部署完成后,可以绑定自己的域名,让手机、电脑等设备直接通过固定地址访问。
🧩 适合什么场景?
PeerClip 更偏向于临时、轻量、多设备之间的数据搬运。
例如:
💻 电脑 → 手机
电脑上复制一段文字、截图或者文件,打开 PeerClip 后直接发送,手机扫码进入房间即可拿到。
📱 手机 → 电脑
手机拍了一张照片或者保存了一份文件,不需要通过微信、QQ、邮件中转,直接上传到房间,在电脑上下载即可。
🧑💻 开发场景
开发过程中经常需要在不同设备之间传:
URL
代码片段
JSON
Token
Shell 命令
配置文件
截图
日志
PeerClip 可以作为一个临时的「中转站」。
🏠 多设备临时共享
家里同时使用 Mac、Windows、iPhone、Android 等设备时,可以建立一个长期使用的房间,把它当成个人的跨设备剪贴板。
⚠️ 注意事项
由于 PeerClip 的定位是临时传输工具,部署时仍然需要注意以下几点:
- R2 API Token 使用最小权限,只授权指定 Bucket。
- 不要提交
.env.local,尤其是 Redis 密码和 R2 Secret Access Key。 - 如果怀疑密钥泄露,应立即撤销旧 Token 并重新生成。
- 浏览器的系统剪贴板读取能力通常需要 HTTPS 或
localhost环境。 - R2 文件建议配置 Lifecycle Rules,自动清理长期未使用的文件,避免存储空间持续增长。
- Redis 中的单条消息不建议存储过大的 Payload,图片和文件应该交给 R2。
💡 项目亮点
PeerClip 最有意思的地方并不是「做了一个文件上传页面」,而是把几个看似简单的问题组合到了一起:
如何用一个纯 Web 应用,把不同设备变成一个临时的共享剪贴板?
它最终采用了:
房间机制
→ 解决多设备如何进入同一个空间。
二维码
→ 解决手机加入房间时输入地址麻烦的问题。
设备审批
→ 解决共享链接带来的陌生设备访问问题。
Redis
→ 解决 Serverless 环境下的数据持久化问题。
R2 Presigned URL
→ 解决图片和文件上传不应该经过 Serverless Function 的问题。
乐观更新 + 轮询
→ 在不引入 WebSocket 的情况下,让同步体验尽可能接近实时。
整个项目的技术实现比较克制,没有为了「实时同步」就强行引入复杂的长连接基础设施,而是根据实际使用场景选择了更简单的轮询方案。
📌 总结
PeerClip 是一个小而完整的跨设备临时传输工具。
它用浏览器作为统一入口,通过房间机制连接不同设备,再结合 Redis、Cloudflare R2 和 Vercel,把:
文本、图片、文件 → 一个房间 → 所有已批准设备
这条链路做得足够简单。
如果你经常需要在电脑和手机之间传文字、截图、文件,又不想安装额外客户端,那么 PeerClip 会是一个比较轻量的解决方案。
项目采用 MIT License,可以直接 Fork、修改并自行部署。