Skip to content

Commit

Permalink
Merge pull request #567 from shiguredo/feature/improve-types
Browse files Browse the repository at this point in the history
Feature/improve types
  • Loading branch information
voluntas authored Oct 2, 2024
2 parents a127880 + 68c2bc1 commit bba0957
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 62 deletions.
112 changes: 73 additions & 39 deletions packages/sdk/src/base.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
import {
DATA_CHANNEL_LABEL_NOTIFY,
DATA_CHANNEL_LABEL_PUSH,
DATA_CHANNEL_LABEL_SIGNALING,
DATA_CHANNEL_LABEL_STATS,
SIGNALING_MESSAGE_TYPE_ANSWER,
SIGNALING_MESSAGE_TYPE_CANDIDATE,
SIGNALING_MESSAGE_TYPE_CLOSE,
SIGNALING_MESSAGE_TYPE_DISCONNECT,
SIGNALING_MESSAGE_TYPE_NOTIFY,
SIGNALING_MESSAGE_TYPE_OFFER,
SIGNALING_MESSAGE_TYPE_PING,
SIGNALING_MESSAGE_TYPE_PONG,
SIGNALING_MESSAGE_TYPE_PUSH,
SIGNALING_MESSAGE_TYPE_REDIRECT,
SIGNALING_MESSAGE_TYPE_REQ_STATS,
SIGNALING_MESSAGE_TYPE_RE_ANSWER,
SIGNALING_MESSAGE_TYPE_RE_OFFER,
SIGNALING_MESSAGE_TYPE_STATS,
SIGNALING_MESSAGE_TYPE_SWITCHED,
SIGNALING_MESSAGE_TYPE_UPDATE,
SIGNALING_ROLE_RECVONLY,
SIGNALING_ROLE_SENDONLY,
SIGNALING_ROLE_SENDRECV,
TRANSPORT_TYPE_DATACHANNEL,
TRANSPORT_TYPE_WEBSOCKET,
} from './constants'
import {
DisconnectDataChannelError,
DisconnectInternalError,
Expand All @@ -7,10 +34,10 @@ import type {
Callbacks,
ConnectionOptions,
DataChannelConfiguration,
DataChannelSignalingMessage,
JSONType,
SignalingCloseMessage,
SignalingConnectMessage,
SignalingMessage,
SignalingNotifyMessage,
SignalingOfferMessage,
SignalingOfferMessageDataChannel,
Expand All @@ -26,6 +53,7 @@ import type {
SoraCloseEventInitDict,
SoraCloseEventType,
TransportType,
WebSocketSignalingMessage,
} from './types'
import {
ConnectError,
Expand Down Expand Up @@ -678,7 +706,7 @@ export default class ConnectionBase {
}
// 終了処理を開始する
if (this.soraDataChannels.signaling) {
const message = { type: 'disconnect', reason: title }
const message = { type: SIGNALING_MESSAGE_TYPE_DISCONNECT, reason: title }
if (
this.signalingOfferMessageDataChannels.signaling &&
this.signalingOfferMessageDataChannels.signaling.compress === true
Expand Down Expand Up @@ -812,7 +840,7 @@ export default class ConnectionBase {
return resolve({ code: event.code, reason: event.reason })
}
if (this.ws.readyState === 1) {
const message = { type: 'disconnect', reason: title }
const message = { type: SIGNALING_MESSAGE_TYPE_DISCONNECT, reason: title }
this.ws.send(JSON.stringify(message))
this.writeWebSocketSignalingLog('send-disconnect', message)
// WebSocket 切断を待つ
Expand Down Expand Up @@ -890,7 +918,7 @@ export default class ConnectionBase {
const dataChannelClosePromise = Promise.all(onDataChannelClosePromises)

// 準備はできたのでメッセージを送る
const message = { type: 'disconnect', reason: 'NO-ERROR' }
const message = { type: SIGNALING_MESSAGE_TYPE_DISCONNECT, reason: 'NO-ERROR' }
if (
this.signalingOfferMessageDataChannels.signaling &&
this.signalingOfferMessageDataChannels.signaling.compress === true
Expand Down Expand Up @@ -1185,33 +1213,33 @@ export default class ConnectionBase {
if (typeof event.data !== 'string') {
throw new Error('Received invalid signaling data')
}
const message = JSON.parse(event.data) as SignalingMessage
if (message.type === 'offer') {
const message = JSON.parse(event.data) as WebSocketSignalingMessage
if (message.type === SIGNALING_MESSAGE_TYPE_OFFER) {
this.writeWebSocketSignalingLog('onmessage-offer', message)
this.signalingOnMessageTypeOffer(message)
this.connectedSignalingUrl = ws.url
resolve(message)
} else if (message.type === 'update') {
} else if (message.type === SIGNALING_MESSAGE_TYPE_UPDATE) {
this.writeWebSocketSignalingLog('onmessage-update', message)
await this.signalingOnMessageTypeUpdate(message)
} else if (message.type === 're-offer') {
} else if (message.type === SIGNALING_MESSAGE_TYPE_RE_OFFER) {
this.writeWebSocketSignalingLog('onmessage-re-offer', message)
await this.signalingOnMessageTypeReOffer(message)
} else if (message.type === 'ping') {
} else if (message.type === SIGNALING_MESSAGE_TYPE_PING) {
await this.signalingOnMessageTypePing(message)
} else if (message.type === 'push') {
this.callbacks.push(message, 'websocket')
} else if (message.type === 'notify') {
} else if (message.type === SIGNALING_MESSAGE_TYPE_PUSH) {
this.callbacks.push(message, TRANSPORT_TYPE_WEBSOCKET)
} else if (message.type === SIGNALING_MESSAGE_TYPE_NOTIFY) {
if (message.event_type === 'connection.created') {
this.writeWebSocketTimelineLog('notify-connection.created', message)
} else if (message.event_type === 'connection.destroyed') {
this.writeWebSocketTimelineLog('notify-connection.destroyed', message)
}
this.signalingOnMessageTypeNotify(message, 'websocket')
} else if (message.type === 'switched') {
this.signalingOnMessageTypeNotify(message, TRANSPORT_TYPE_WEBSOCKET)
} else if (message.type === SIGNALING_MESSAGE_TYPE_SWITCHED) {
this.writeWebSocketSignalingLog('onmessage-switched', message)
this.signalingOnMessageTypeSwitched(message)
} else if (message.type === 'redirect') {
} else if (message.type === SIGNALING_MESSAGE_TYPE_REDIRECT) {
this.writeWebSocketSignalingLog('onmessage-redirect', message)
try {
const redirectMessage = await this.signalingOnMessageTypeRedirect(message)
Expand Down Expand Up @@ -1317,7 +1345,7 @@ export default class ConnectionBase {

const sdp = this.processOfferSdp(message.sdp)
const sessionDescription = new RTCSessionDescription({
type: 'offer',
type: SIGNALING_MESSAGE_TYPE_OFFER,
sdp,
})
await this.pc.setRemoteDescription(sessionDescription)
Expand All @@ -1342,20 +1370,23 @@ export default class ConnectionBase {
// mid と transceiver.direction を合わせる
for (const mid of Object.values(this.mids)) {
const transceiver = this.pc.getTransceivers().find((t) => t.mid === mid)
if (transceiver && transceiver.direction === 'recvonly') {
transceiver.direction = 'sendrecv'
if (transceiver && transceiver.direction === SIGNALING_ROLE_RECVONLY) {
transceiver.direction = SIGNALING_ROLE_SENDRECV
}
}
// simulcast の場合
if (this.simulcast && (this.role === 'sendrecv' || this.role === 'sendonly')) {
if (
this.simulcast &&
(this.role === SIGNALING_ROLE_SENDRECV || this.role === SIGNALING_ROLE_SENDONLY)
) {
const transceiver = this.pc.getTransceivers().find((t) => {
if (t.mid === null) {
return
}
if (t.sender.track === null) {
return
}
if (t.currentDirection !== null && t.currentDirection !== 'sendonly') {
if (t.currentDirection !== null && t.currentDirection !== SIGNALING_ROLE_SENDONLY) {
return
}
if (this.mids.video !== '' && this.mids.video === t.mid) {
Expand Down Expand Up @@ -1412,7 +1443,7 @@ export default class ConnectionBase {
if (this.pc && this.ws && this.pc.localDescription) {
this.trace('ANSWER SDP', this.pc.localDescription.sdp)
const sdp = this.pc.localDescription.sdp
const message = { type: 'answer', sdp }
const message = { type: SIGNALING_MESSAGE_TYPE_ANSWER, sdp }
this.ws.send(JSON.stringify(message))
this.writeWebSocketSignalingLog('send-answer', message)
}
Expand Down Expand Up @@ -1448,7 +1479,9 @@ export default class ConnectionBase {
resolve()
} else {
const candidate = event.candidate.toJSON()
const message = Object.assign(candidate, { type: 'candidate' }) as {
const message = Object.assign(candidate, {
type: SIGNALING_MESSAGE_TYPE_CANDIDATE,
}) as {
type: string
[key: string]: unknown
}
Expand Down Expand Up @@ -1673,7 +1706,7 @@ export default class ConnectionBase {
* @param data - イベントデータ
*/
protected writeWebSocketSignalingLog(eventType: string, data?: unknown): void {
this.callbacks.signaling(createSignalingEvent(eventType, data, 'websocket'))
this.callbacks.signaling(createSignalingEvent(eventType, data, TRANSPORT_TYPE_WEBSOCKET))
this.writeWebSocketTimelineLog(eventType, data)
}

Expand All @@ -1688,7 +1721,7 @@ export default class ConnectionBase {
channel: RTCDataChannel,
data?: unknown,
): void {
this.callbacks.signaling(createSignalingEvent(eventType, data, 'datachannel'))
this.callbacks.signaling(createSignalingEvent(eventType, data, TRANSPORT_TYPE_DATACHANNEL))
this.writeDataChannelTimelineLog(eventType, channel, data)
}

Expand All @@ -1699,7 +1732,7 @@ export default class ConnectionBase {
* @param data - イベントデータ
*/
protected writeWebSocketTimelineLog(eventType: string, data?: unknown): void {
const event = createTimelineEvent(eventType, data, 'websocket')
const event = createTimelineEvent(eventType, data, TRANSPORT_TYPE_WEBSOCKET)
this.callbacks.timeline(event)
}

Expand Down Expand Up @@ -1806,12 +1839,13 @@ export default class ConnectionBase {

/**
* シグナリングサーバーに type update を投げるメソッド
* @deprecated このメソッドは非推奨です。将来のバージョンで削除される可能性があります。
*/
private async sendUpdateAnswer(): Promise<void> {
if (this.pc && this.ws && this.pc.localDescription) {
this.trace('ANSWER SDP', this.pc.localDescription.sdp)
this.trace('UPDATE ANSWER SDP', this.pc.localDescription.sdp)
await this.sendSignalingMessage({
type: 'update',
type: SIGNALING_MESSAGE_TYPE_UPDATE,
sdp: this.pc.localDescription.sdp,
})
}
Expand All @@ -1824,7 +1858,7 @@ export default class ConnectionBase {
if (this.pc?.localDescription) {
this.trace('RE ANSWER SDP', this.pc.localDescription.sdp)
await this.sendSignalingMessage({
type: 're-answer',
type: SIGNALING_MESSAGE_TYPE_RE_ANSWER,
sdp: this.pc.localDescription.sdp,
})
}
Expand Down Expand Up @@ -1872,8 +1906,8 @@ export default class ConnectionBase {
* @param message - type ping メッセージ
*/
private async signalingOnMessageTypePing(message: SignalingPingMessage): Promise<void> {
const pongMessage: { type: 'pong'; stats?: RTCStatsReport[] } = {
type: 'pong',
const pongMessage: { type: typeof SIGNALING_MESSAGE_TYPE_PONG; stats?: RTCStatsReport[] } = {
type: SIGNALING_MESSAGE_TYPE_PONG,
}
if (message.stats) {
const stats = await this.getStats()
Expand Down Expand Up @@ -2022,7 +2056,7 @@ export default class ConnectionBase {
})
}
// onmessage
if (dataChannelEvent.channel.label === 'signaling') {
if (dataChannelEvent.channel.label === DATA_CHANNEL_LABEL_SIGNALING) {
dataChannelEvent.channel.onmessage = async (event): Promise<void> => {
const channel = event.currentTarget as RTCDataChannel
const label = channel.label
Expand All @@ -2034,15 +2068,15 @@ export default class ConnectionBase {
return
}
const data = await parseDataChannelEventData(event.data, dataChannelSettings.compress)
const message = JSON.parse(data) as SignalingMessage
const message = JSON.parse(data) as DataChannelSignalingMessage
this.writeDataChannelSignalingLog(`onmessage-${message.type}`, channel, message)
if (message.type === 're-offer') {
if (message.type === SIGNALING_MESSAGE_TYPE_RE_OFFER) {
await this.signalingOnMessageTypeReOffer(message)
} else if (message.type === 'close') {
} else if (message.type === SIGNALING_MESSAGE_TYPE_CLOSE) {
await this.signalingOnMessageTypeClose(message)
}
}
} else if (dataChannelEvent.channel.label === 'notify') {
} else if (dataChannelEvent.channel.label === DATA_CHANNEL_LABEL_NOTIFY) {
dataChannelEvent.channel.onmessage = async (event): Promise<void> => {
const channel = event.currentTarget as RTCDataChannel
const label = channel.label
Expand All @@ -2062,7 +2096,7 @@ export default class ConnectionBase {
}
this.signalingOnMessageTypeNotify(message, 'datachannel')
}
} else if (dataChannelEvent.channel.label === 'push') {
} else if (dataChannelEvent.channel.label === DATA_CHANNEL_LABEL_PUSH) {
dataChannelEvent.channel.onmessage = async (event): Promise<void> => {
const channel = event.currentTarget as RTCDataChannel
const label = channel.label
Expand All @@ -2077,7 +2111,7 @@ export default class ConnectionBase {
const message = JSON.parse(data) as SignalingPushMessage
this.callbacks.push(message, 'datachannel')
}
} else if (dataChannelEvent.channel.label === 'stats') {
} else if (dataChannelEvent.channel.label === DATA_CHANNEL_LABEL_STATS) {
dataChannelEvent.channel.onmessage = async (event): Promise<void> => {
const channel = event.currentTarget as RTCDataChannel
const label = channel.label
Expand All @@ -2090,7 +2124,7 @@ export default class ConnectionBase {
}
const data = await parseDataChannelEventData(event.data, dataChannelSettings.compress)
const message = JSON.parse(data) as SignalingReqStatsMessage
if (message.type === 'req-stats') {
if (message.type === SIGNALING_MESSAGE_TYPE_REQ_STATS) {
const stats = await this.getStats()
await this.sendStatsMessage(stats)
}
Expand Down Expand Up @@ -2168,7 +2202,7 @@ export default class ConnectionBase {
private async sendStatsMessage(reports: RTCStatsReport[]): Promise<void> {
if (this.soraDataChannels.stats) {
const message = {
type: 'stats',
type: SIGNALING_MESSAGE_TYPE_STATS,
reports: reports,
}
if (
Expand Down
39 changes: 39 additions & 0 deletions packages/sdk/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// シグナリングトランスポートタイプ
export const TRANSPORT_TYPE_WEBSOCKET = 'websocket' as const
export const TRANSPORT_TYPE_DATACHANNEL = 'datachannel' as const

// シグナリング ROLE
export const SIGNALING_ROLE_SENDRECV = 'sendrecv' as const
export const SIGNALING_ROLE_SENDONLY = 'sendonly' as const
export const SIGNALING_ROLE_RECVONLY = 'recvonly' as const

// WebSocket シグナリングでのみ利用する
export const SIGNALING_MESSAGE_TYPE_CONNECT = 'connect' as const
export const SIGNALING_MESSAGE_TYPE_REDIRECT = 'redirect' as const
export const SIGNALING_MESSAGE_TYPE_OFFER = 'offer' as const
export const SIGNALING_MESSAGE_TYPE_ANSWER = 'answer' as const
export const SIGNALING_MESSAGE_TYPE_CANDIDATE = 'candidate' as const
export const SIGNALING_MESSAGE_TYPE_SWITCHED = 'switched' as const
export const SIGNALING_MESSAGE_TYPE_PING = 'ping' as const
export const SIGNALING_MESSAGE_TYPE_PONG = 'pong' as const

// DataChannel シグナリングでのみ利用する
export const SIGNALING_MESSAGE_TYPE_REQ_STATS = 'req-stats' as const
export const SIGNALING_MESSAGE_TYPE_STATS = 'stats' as const
export const SIGNALING_MESSAGE_TYPE_CLOSE = 'close' as const

// WebSocket と DataChannel シグナリング両方で了する
export const SIGNALING_MESSAGE_TYPE_RE_OFFER = 're-offer' as const
export const SIGNALING_MESSAGE_TYPE_RE_ANSWER = 're-answer' as const
export const SIGNALING_MESSAGE_TYPE_DISCONNECT = 'disconnect' as const
export const SIGNALING_MESSAGE_TYPE_NOTIFY = 'notify' as const
export const SIGNALING_MESSAGE_TYPE_PUSH = 'push' as const

// @deprecated この定数は将来的に削除される予定です
export const SIGNALING_MESSAGE_TYPE_UPDATE = 'update' as const

// データチャネル必須ラベル
export const DATA_CHANNEL_LABEL_SIGNALING = 'signaling' as const
export const DATA_CHANNEL_LABEL_PUSH = 'push' as const
export const DATA_CHANNEL_LABEL_NOTIFY = 'notify' as const
export const DATA_CHANNEL_LABEL_STATS = 'stats' as const
Loading

0 comments on commit bba0957

Please sign in to comment.