AdonisJS 传输客户端
AdonisJS的本地服务器-Sent-Event(SSE)模块的客户端.
AdonisJS Transmit客户端是AdonisJS的本地服务器-Sent-Event(SSE)模块的客户端. 它建在顶上 事件来源 API并提供一个简单的API来接收来自服务器的事件.
目录
安装
从 npm 登记册中安装软件包如下:
npm i @adonisjs/transmit-client
使用量
模块显示 Transmit class,可以用来连接服务器并收听事件.
import { Transmit } from '@adonisjs/transmit-client'
const transmit = new Transmit({
baseUrl: 'http://localhost:3333',
})
创建订阅
这个 subscription 方法用于创建频道的订阅。 该方法接受频道名称
const subscription = transmit.subscription('chat/1')
那么,你必须打电话给 create 用于订阅后端注册的方法.
await subscription.create()
您可以使用 onMessage 方法。 您可以在同一订阅上定义尽可能多的听众.
subscription.onMessage((message) => {
console.log(message)
})
您也可以只听一次使用 onMessagetOnce 方法.
subscription.onMessageOnce((message) => {
console.log('I will be called only once')
})
Note 收听器只属于本地;您可以在服务器注册订阅之前或之后添加它们.
取消订阅
这个 onMessage 方法返回从订阅中删除信件处理器的函数.
const unsubscribe = subscription.onMessage(() => {
console.log('message received!')
})
// later
unsubscribe()
如果您想从服务器上完全删除订阅, 您可以拨打 delete 方法.
await subscription.delete()
订阅请求
您可以使用 beforeSubscribe 或者说 beforeUnsubscribe 选项.
const transmit = new Transmit({
baseUrl: 'http://localhost:3333',
beforeSubscribe: (_request: Request) => {
console.log('beforeSubscribe')
},
beforeUnsubscribe: (_request: Request) => {
console.log('beforeUnsubscribe')
},
})
已认证的事件流
这个 __transmit/events 使用 EventSource,它不能发送自定义标题。 这意味着 beforeSubscribe编号 :beforeUnsubscribe 只影响订阅/不订阅 HTTP 调用。 如果您依赖基于信头的认证, 请保护 __transmit/subscribe 财务报告和审定财务报表 __transmit/unsubscribe,或提供习惯 eventSourceFactory 可以发送信头.
使用示例 @microsoft/fetch-event-source数字 :
import { fetchEventSource } from '@microsoft/fetch-event-source'
function createFetchEventSource(
url: string | URL,
options: { withCredentials: boolean },
headers: Record<string, string>
) {
const controller = new AbortController()
const listeners = new Map<string, Set<(event: MessageEvent) => void>>()
const dispatch = (type: string, data?: string) => {
const event = new MessageEvent(type, { data })
listeners.get(type)?.forEach((listener) => listener(event))
}
fetchEventSource(url.toString(), {
headers,
credentials: options.withCredentials ? 'include' : 'omit',
signal: controller.signal,
onopen: () => dispatch('open'),
onmessage: (message) => dispatch(message.event ?? 'message', message.data),
onerror: () => {
dispatch('error')
},
})
return {
addEventListener(type: string, listener: (event: MessageEvent) => void) {
if (!listeners.has(type)) {
listeners.set(type, new Set())
}
listeners.get(type)!.add(listener)
},
removeEventListener(type: string, listener: (event: MessageEvent) => void) {
listeners.get(type)?.delete(listener)
},
close() {
controller.abort()
},
} as EventSource
}
const transmit = new Transmit({
baseUrl: 'http://localhost:3333',
eventSourceFactory: (url, options) => {
return createFetchEventSource(url, options, {
Authorization: `Bearer ${token}`,
})
},
})
注意: 此适配器是最小的, 只有电线 open, (中文(简体) ), error,以及 message (或自定义事件名称). 如果你依赖别人 EventSource 功能类 readyState 或者说 onopen,你可能想要扩展它.
自定义 UID 生成器
默认情况下, 传输使用 crypto.randomUUID() 生成唯一的客户端标识符。 这种方法只在 安全环境 (HTTPS) (韩语). 如果您需要通过 HTTP 传输( 例如本地网络部署) , 您可以提供自定义 uidGenerator 函数.
const transmit = new Transmit({
baseUrl: 'http://localhost:3333',
uidGenerator: () => {
return Array.from({ length: 16 }, () =>
Math.floor(Math.random() * 256).toString(16).padStart(2, '0')
).join('')
},
})
或者利用图书馆 uuid数字 :
import { v4 as uuid } from 'uuid'
const transmit = new Transmit({
baseUrl: 'http://localhost:3333',
uidGenerator: () => uuid(),
})
重新连接
传输客户端将在连接丢失时自动重接服务器. 可以改变重试和钩入重联生命周期的次数如下:
const transmit = new Transmit({
baseUrl: 'http://localhost:3333',
maxReconnectionAttempts: 5,
onReconnectAttempt: (attempt) => {
console.log('Reconnect attempt ' + attempt)
},
onReconnectFailed: () => {
console.log('Reconnect failed')
},
})
活动
这个 Transmit 类使用 EventTarget 类以释放多个事件.
transmit.on('connected', () => {
console.log('connected')
})
transmit.on('disconnected', () => {
console.log('disconnected')
})
transmit.on('reconnecting', () => {
console.log('reconnecting')
})
这意味着您也可以通过通过事件听器本身的功能来去除先前注册的事件听器.
const onConnected = () => {
console.log('connected')
}
transmit.on('connected', onConnected)
transmit.off('connected', onConnected)