Skip to content

Commit

Permalink
feat: add deSerialize and Serialize data
Browse files Browse the repository at this point in the history
  • Loading branch information
starknt committed Sep 26, 2022
1 parent cfbae22 commit 72eb2e6
Show file tree
Hide file tree
Showing 13 changed files with 2,757 additions and 6 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@
"build": "unbuild",
"prepublishOnly": "pnpm run build",
"release": "bumpp && pnpm publish",
"start": "esno ./src/index.ts",
"start": "esno ./src/node.ts",
"dev": "unbuild --stub",
"typecheck": "npx tsc --noEmit",
"test": "vitest",
"lint": "eslint ."
},
"dependencies": {
"@gfx/zopfli": "^1.0.15",
"eventemitter3": "^4.0.7",
"isomorphic-ws": "^5.0.0",
"pako": "^2.0.4",
Expand Down
4 changes: 1 addition & 3 deletions playground/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import { KeepLiveTCP } from 'tiny-bilibili-ws/browser'
import { onMounted } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
onMounted(() => {
new KeepLiveTCP(10647165)
new KeepLiveTCP(1017)
})
</script>

Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 96 additions & 0 deletions src/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import EventEmitter from 'eventemitter3'
import type { IZlib } from './buffer'
import { LiveProtocolOperation, deserialize, serialize } from './buffer'
import type { ISocket } from './types'

export interface LiveHelloMessage {
clientver: `${number}.${number}.${number}`
platform: 'web'
protover: 2
roomid: number
uid: 0
type: 2
}

export const MESSAGE_EVENT = Symbol('')
export const OPEN_EVENT = Symbol('')
export const ERROR_EVENT = Symbol('')
export const CLOSE_EVENT = Symbol('')

export type ListenerEvents = 'msg' | 'message' | 'open' | 'close' | 'error' | 'live'

export class Live extends EventEmitter<ListenerEvents | symbol | string> {
readonly roomId: number

timeout: any

constructor(roomId: number, private readonly _socket: ISocket, readonly zlib: IZlib<Buffer>) {
if (typeof roomId !== 'number' || Number.isNaN(roomId))
throw new Error(`roomId ${roomId} must be Number not NaN`)

super()

this.on(OPEN_EVENT, () => {
const helloMessage: LiveHelloMessage = {
clientver: '2.0.11',
platform: 'web',
protover: 2,
roomid: this.roomId,
uid: 0,
type: 2,
}

this._socket.write(serialize(LiveProtocolOperation.USER_AUTHENTICATION, helloMessage))
this.emit('live')
})

this.roomId = roomId
this.bindEvent()
}

private bindEvent() {
this.on(MESSAGE_EVENT, async (buffer: Uint8Array) => {
const packs = await deserialize(buffer, this.zlib)

packs.forEach(({ type, data }) => {
if (type === 'welcome') {
this.emit('live')
this._socket.write(serialize(LiveProtocolOperation.HEARTBEAT, {}))
}
if (type === 'heartbeat')
this.timeout = setTimeout(() => this.heartbeat(), 1000 * 30)
// this.emit('heartbeat', this.online)

if (type === 'message') {
console.log(data)
this.emit('msg', data)
const cmd = data?.cmd || (data?.msg && data?.msg?.cmd)
if (cmd) {
if (cmd.includes('DANMU_MSG'))

this.emit('DANMU_MSG', data)

else this.emit(cmd, data)
}
}
})
})

this.on(ERROR_EVENT, (error: any) => {
this.emit('error', error)
})

this.on(CLOSE_EVENT, () => {
this.emit('close')
})
}

heartbeat() {
this._socket.write(serialize(LiveProtocolOperation.HEARTBEAT, {}))
}

getOnline() {
this.heartbeat()
// return new Promise<number>(resolve => this.once('heartbeat', resolve))
}
}
33 changes: 33 additions & 0 deletions src/browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { CLOSE_EVENT, ERROR_EVENT, Live, MESSAGE_EVENT, OPEN_EVENT } from './base'
import type { ISocket } from './types'
import { inflates } from './inflate/browser'

export class KeepLiveTCP extends Live {
private socket: WebSocket
i = 0

constructor(roomId: number) {
const socket = new WebSocket('wss://broadcastlv.chat.bilibili.com:2245/sub')
socket.binaryType = 'arraybuffer'
const _socket: ISocket = {
write(buffer) {
socket.send(new Uint8Array(buffer))
},
end() {
socket.close()
},
}

socket.addEventListener('open', () => this.emit(OPEN_EVENT))
socket.addEventListener('close', () => this.emit(CLOSE_EVENT))
socket.addEventListener('error', (...params: any[]) => this.emit(ERROR_EVENT, ...params))
socket.addEventListener('message', (e: MessageEvent<ArrayBuffer>) => {
this.emit(MESSAGE_EVENT, new Uint8Array(e.data))
})

super(roomId, _socket, inflates as any)

this.socket = socket
}
}

Loading

0 comments on commit 72eb2e6

Please sign in to comment.