快速开始
安装
bash
pnpm add @wetspace/wetrtc
# or
npm install @wetspace/wetrtc
# or
yarn add @wetspace/wetrtc基本用法
WetRTC 需要一个信令通道来交换 SDP 和 ICE 候选。你需要实现 SignalChannel 接口,传输层可任选 WebSocket、SSE + HTTP 或纯 HTTP 长轮询:
WebSocket
ts
import type { SignalChannel } from '@wetspace/wetrtc'
const ws = new WebSocket('wss://signal.example.com')
export const signal: SignalChannel = {
async send(data) {
ws.send(JSON.stringify(data))
},
onMessage(handler) {
const listener = (e: MessageEvent) => handler(JSON.parse(e.data))
ws.addEventListener('message', listener)
return () => ws.removeEventListener('message', listener)
},
}SSE + HTTP
发送走 POST,接收走 EventSource(Server-Sent Events)。适合只需服务端→客户端推送、客户端→服务端用 HTTP 的场景:
ts
import type { SignalChannel } from '@wetspace/wetrtc'
const ROOM_ID = 'my-room'
const BASE = 'https://signal.example.com'
/** 服务端约定:POST 发送信令,GET /events 以 SSE 推送远端消息 */
export const signal: SignalChannel = {
async send(data) {
await fetch(`${BASE}/api/signal?room=${ROOM_ID}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
})
},
onMessage(handler) {
const es = new EventSource(`${BASE}/api/signal/events?room=${ROOM_ID}`)
es.onmessage = (e) => handler(JSON.parse(e.data))
es.onerror = () => es.close()
return () => es.close()
},
}HTTP 长轮询
不依赖 WebSocket 或 SSE,仅用 fetch 实现。/poll 端点应在无消息时挂起连接,有信令时立即返回:
ts
import type { SignalChannel } from '@wetspace/wetrtc'
const ROOM_ID = 'my-room'
const BASE = 'https://signal.example.com'
/** 服务端约定:POST 发送信令,GET /poll 长轮询拉取远端消息(无消息时挂起,有消息立即返回) */
export const signal: SignalChannel = {
async send(data) {
await fetch(`${BASE}/api/signal?room=${ROOM_ID}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
})
},
onMessage(handler) {
let active = true
const poll = async () => {
while (active) {
try {
const res = await fetch(`${BASE}/api/signal/poll?room=${ROOM_ID}`)
if (res.ok) {
const msg = await res.json()
if (msg) handler(msg)
}
} catch {
await new Promise((r) => setTimeout(r, 1000))
}
}
}
poll()
return () => {
active = false
}
},
}创建实例并连接:
ts
import { WetRTC, type SignalChannel } from '@wetspace/wetrtc'
declare const signal: SignalChannel
declare const remoteVideo: HTMLVideoElement
const rtc = new WetRTC({
signal,
direction: 'sendrecv',
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
})
rtc.on('track', (ev) => {
remoteVideo.srcObject = ev.streams[0]
})
await rtc.connect()连接方向
| 方向 | 说明 |
|---|---|
sendrecv | 双向(默认),可发送和接收媒体 |
sendonly | 仅发送,不接收远端媒体 |
recvonly | 仅接收,不发送本地媒体 |
生命周期
ts
// rtc 为已创建的 WetRTC 实例
declare const rtc: import('@wetspace/wetrtc').WetRTC
await rtc.connect()
await rtc.disconnect()
await rtc.connect()
rtc.dispose()