odkkk
PeerClip · 跨设备剪贴板同步

PeerClip · 跨设备剪贴板同步

一次部署,多端通用。把你的 PC、Mac、iPhone、Android、平板都拉进同一个「房间」,随手粘贴文本、图片和文件。

Next.js React Tailwind CSS TypeScript Redis Cloudflare R2 Vercel

项目介绍

PeerClip 是一个面向多设备场景的临时文件与剪贴板传输工具。

它不需要安装原生客户端,只需要打开浏览器,就可以把 PC、Mac、iPhone、Android、平板 等设备加入同一个房间,在设备之间快速同步文本、图片以及文件。

项目采用「房间 + 设备审批」的机制管理访问权限,并通过二维码降低移动端加入房间的操作成本。文本消息通过 Redis 持久化,图片和文件则使用 Cloudflare R2 存储,并通过预签名 URL 实现浏览器直传。

查看 PeerClip 源码

✨ 核心特性

🔗 房间机制

首次打开 PeerClip 时会自动生成唯一的房间 ID,并通过 URL 中的 ?room=xxx 标识当前房间。

只需要分享房间链接,或者让其他设备扫描页面上的二维码,就可以快速加入同一个空间。

📱 二维码快速加入

页面内置房间二维码。

手机或平板无需手动输入房间号,直接扫码即可进入当前房间,非常适合电脑与手机之间临时传输内容。

🔐 设备审批

为了避免房间链接被误分享后产生陌生设备加入,PeerClip 引入了设备审批机制。

  • 第一个进入房间的设备自动成为管理员
  • 后续设备默认处于 pending 状态
  • 管理员可以选择 ApproveReject
  • 只有通过审批的设备才能查看和发送房间内容

在保持使用简单的同时,也增加了一层基础的访问控制。

📝 文本即时同步

在任意设备输入或粘贴文本,发送后其他已批准设备即可看到消息。

同时提供一键复制按钮,可以直接把内容复制回当前设备的系统剪贴板。

对于临时传输:

一段代码、一条命令、一个链接、一段配置,都可以直接丢进房间。

🖼️ 多图片传输

支持一次选择多张图片,并以卡片轮播的形式展示。

移动端还针对图片预览增加了触控操作:

  • 双击放大 / 还原
  • 单指拖动图片
  • 双指捏合缩放
  • 全屏查看

对于电脑截图后传到手机这样的场景尤其方便。

📎 通用文件上传

除了图片之外,也支持其他类型的文件,例如:

  • 压缩包
  • 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 环境下,也不会因为函数冷启动或实例变化导致数据完全丢失。


🛠 技术栈

层级技术用途
FrameworkNext.js 16App Router、页面与 API
UIReact 19前端交互与组件
StylingTailwind CSS 4原子化 CSS
LanguageTypeScript 5类型安全
Iconslucide-reactSVG 图标
QR Codeqrcode.react房间二维码
DatabaseRedis / ioredis房间、设备、消息持久化
File StorageCloudflare R2图片与文件存储
UploadPresigned URL浏览器直传 R2
DeploymentVercelServerless 部署

项目实际采用 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 的定位是临时传输工具,部署时仍然需要注意以下几点:

  1. R2 API Token 使用最小权限,只授权指定 Bucket。
  2. 不要提交 .env.local,尤其是 Redis 密码和 R2 Secret Access Key。
  3. 如果怀疑密钥泄露,应立即撤销旧 Token 并重新生成。
  4. 浏览器的系统剪贴板读取能力通常需要 HTTPS 或 localhost 环境。
  5. R2 文件建议配置 Lifecycle Rules,自动清理长期未使用的文件,避免存储空间持续增长。
  6. Redis 中的单条消息不建议存储过大的 Payload,图片和文件应该交给 R2。

💡 项目亮点

PeerClip 最有意思的地方并不是「做了一个文件上传页面」,而是把几个看似简单的问题组合到了一起:

如何用一个纯 Web 应用,把不同设备变成一个临时的共享剪贴板?

它最终采用了:

房间机制

→ 解决多设备如何进入同一个空间。

二维码

→ 解决手机加入房间时输入地址麻烦的问题。

设备审批

→ 解决共享链接带来的陌生设备访问问题。

Redis

→ 解决 Serverless 环境下的数据持久化问题。

R2 Presigned URL

→ 解决图片和文件上传不应该经过 Serverless Function 的问题。

乐观更新 + 轮询

→ 在不引入 WebSocket 的情况下,让同步体验尽可能接近实时。

整个项目的技术实现比较克制,没有为了「实时同步」就强行引入复杂的长连接基础设施,而是根据实际使用场景选择了更简单的轮询方案。


📌 总结

PeerClip 是一个小而完整的跨设备临时传输工具。

它用浏览器作为统一入口,通过房间机制连接不同设备,再结合 Redis、Cloudflare R2 和 Vercel,把:

文本、图片、文件 → 一个房间 → 所有已批准设备

这条链路做得足够简单。

如果你经常需要在电脑和手机之间传文字、截图、文件,又不想安装额外客户端,那么 PeerClip 会是一个比较轻量的解决方案。

项目采用 MIT License,可以直接 Fork、修改并自行部署。

GitHub · Licy711/lan-clipboard