mirror of
https://github.com/ragestudio/linebridge.git
synced 2025-06-09 02:24:17 +00:00
slit server source & client source
This commit is contained in:
parent
7136402109
commit
0a11a24460
21
client/package.json
Normal file
21
client/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "linebridge-client",
|
||||
"version": "0.2.0",
|
||||
"main": "./dist/index.js",
|
||||
"author": "RageStudio <support@ragestudio.net>",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"src/**/**",
|
||||
"dist/**/**",
|
||||
"./package.json"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "hermes build --parallel --clean"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ragestudio/hermes": "^1.0.0"
|
||||
}
|
||||
}
|
1
client/src/index.js
Normal file
1
client/src/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default as RTEngineClient } from "./rtengine"
|
149
client/src/rtengine/index.js
Normal file
149
client/src/rtengine/index.js
Normal file
@ -0,0 +1,149 @@
|
||||
import TopicsController from "./topics"
|
||||
|
||||
export class RTEngineClient {
|
||||
constructor(params = {}) {
|
||||
this.params = {
|
||||
maxConnectRetries: 3,
|
||||
...params,
|
||||
}
|
||||
}
|
||||
|
||||
state = {
|
||||
id: null,
|
||||
connected: false,
|
||||
}
|
||||
|
||||
socket = null
|
||||
|
||||
handlers = new Set()
|
||||
|
||||
topics = new TopicsController(this)
|
||||
|
||||
async connect() {
|
||||
if (this.socket) {
|
||||
await this.disconnect()
|
||||
}
|
||||
|
||||
let url = `${this.params.url}`
|
||||
|
||||
if (this.params.token) {
|
||||
url += `?token=${this.params.token}`
|
||||
}
|
||||
|
||||
this.socket = new WebSocket(url)
|
||||
|
||||
this.socket.onopen = (e) => this.#handleOpen(e)
|
||||
this.socket.onclose = (e) => this.#handleClose(e)
|
||||
this.socket.onerror = (e) => this.#handleError(e)
|
||||
this.socket.onmessage = (e) => this.#handleMessage(e)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.once("connected", resolve)
|
||||
})
|
||||
}
|
||||
|
||||
async disconnect() {
|
||||
if (!this.socket) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.topics.unsubscribeAll()
|
||||
this.socket.close()
|
||||
this.socket = null
|
||||
}
|
||||
|
||||
on = (event, handler) => {
|
||||
this.handlers.add({
|
||||
event,
|
||||
handler,
|
||||
})
|
||||
}
|
||||
|
||||
off = (event, handler) => {
|
||||
this.handlers.delete({
|
||||
event,
|
||||
handler,
|
||||
})
|
||||
}
|
||||
|
||||
once = (event, handler) => {
|
||||
this.handlers.add({
|
||||
event,
|
||||
handler,
|
||||
once: true,
|
||||
})
|
||||
}
|
||||
|
||||
emit = async (event, data) => {
|
||||
if (!this.socket) {
|
||||
throw new Error("Failed to send, socket not connected")
|
||||
}
|
||||
|
||||
return await this.socket.send(JSON.stringify({ event, data }))
|
||||
}
|
||||
|
||||
#_decode(payload) {
|
||||
return JSON.parse(payload)
|
||||
}
|
||||
|
||||
//* HANDLERS
|
||||
#handleMessage(event) {
|
||||
try {
|
||||
const payload = this.#_decode(event.data)
|
||||
|
||||
if (typeof payload.event !== "string") {
|
||||
throw new Error("Invalid event or payload")
|
||||
}
|
||||
|
||||
return this.#dispatchToHandlers(payload.event, payload.data)
|
||||
} catch (error) {
|
||||
console.error("Error handling message:", error)
|
||||
}
|
||||
}
|
||||
|
||||
#handleClose() {
|
||||
this.state.connected = false
|
||||
this.#dispatchToHandlers("disconnect")
|
||||
}
|
||||
|
||||
#handleOpen() {
|
||||
this.state.connected = true
|
||||
this.#dispatchToHandlers("connect")
|
||||
}
|
||||
|
||||
#handleError(error) {
|
||||
console.error("WebSocket connection error:", error)
|
||||
this.#dispatchToHandlers("error")
|
||||
}
|
||||
|
||||
baseHandlers = {
|
||||
connected: (data) => {
|
||||
this.state.connected = true
|
||||
|
||||
if (data.id) {
|
||||
this.state.id = data.id
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error)
|
||||
},
|
||||
}
|
||||
|
||||
async #dispatchToHandlers(event, data) {
|
||||
if (this.baseHandlers[event]) {
|
||||
await this.baseHandlers[event](data)
|
||||
}
|
||||
|
||||
for (const handler of this.handlers) {
|
||||
if (handler.event === event) {
|
||||
handler.handler(data)
|
||||
|
||||
if (handler.once === true) {
|
||||
this.handlers.delete(handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default RTEngineClient
|
31
client/src/rtengine/topics.js
Normal file
31
client/src/rtengine/topics.js
Normal file
@ -0,0 +1,31 @@
|
||||
class TopicsController {
|
||||
constructor(client) {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
subscribed = new Set()
|
||||
|
||||
subscribe = async (topic) => {
|
||||
await this.client.emit("topic:subscribe", topic)
|
||||
this.subscribed.add(topic)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
unsubscribe = async (topic) => {
|
||||
await this.client.emit("topic:unsubscribe", topic)
|
||||
this.subscribed.delete(topic)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
unsubscribeAll = async () => {
|
||||
for (const topic of this.subscribed) {
|
||||
await this.leave(topic)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export default TopicsController
|
@ -4,7 +4,7 @@ class Client {
|
||||
this.id = socket.context.id
|
||||
|
||||
this.userId = socket.context.user?._id || null
|
||||
this.authed = !!socket.context.session
|
||||
this.autheticated = !!socket.context.session
|
||||
}
|
||||
|
||||
emit(event, data) {
|
||||
@ -36,10 +36,12 @@ class Client {
|
||||
}
|
||||
|
||||
subscribe(topic) {
|
||||
this.emit("topic:subscribed", topic)
|
||||
return this.socket.subscribe(topic)
|
||||
}
|
||||
|
||||
unsubscribe(topic) {
|
||||
this.emit("topic:unsubscribed", topic)
|
||||
return this.socket.unsubscribe(topic)
|
||||
}
|
||||
}
|
20
server/src/classes/rtengineng/events.js
Normal file
20
server/src/classes/rtengineng/events.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { performance } from "node:perf_hooks"
|
||||
|
||||
export default {
|
||||
"server:ping": async (client, data) => {
|
||||
const pongTime = performance.now()
|
||||
|
||||
return {
|
||||
ping: data.ping ?? 0,
|
||||
pong: pongTime,
|
||||
latency: Number(pongTime - data.ping),
|
||||
latencyMs: Number(pongTime - data.ping).toFixed(2),
|
||||
}
|
||||
},
|
||||
"topic:subscribe": async (client, topic) => {
|
||||
client.subscribe(topic)
|
||||
},
|
||||
"topic:unsubscribe": async (client, topic) => {
|
||||
client.unsubscribe(topic)
|
||||
},
|
||||
}
|
@ -104,6 +104,11 @@ class RTEngineNG {
|
||||
|
||||
const client = new Client(socket)
|
||||
|
||||
await client.emit("connected", {
|
||||
id: client.id,
|
||||
autheticated: client.autheticated,
|
||||
})
|
||||
|
||||
this.clients.set(socket.context.id, client)
|
||||
}
|
||||
|
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
export default {
|
||||
"topic:join": async (client, topic) => {
|
||||
client.subscribe(topic)
|
||||
},
|
||||
"topic:leave": async (client, topic) => {
|
||||
client.unsubscribe(topic)
|
||||
},
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user