2023-09-08 13:39:51 +08:00
|
|
|
import { differenceWith, isNumber, unionWith } from 'lodash'
|
2023-09-08 11:35:53 +08:00
|
|
|
import { Accessor, createEffect, createSignal, untrack } from 'solid-js'
|
2023-09-10 18:47:01 +08:00
|
|
|
import { CONNECTIONS_TABLE_MAX_CLOSED_ROWS } from '~/constants'
|
2023-09-08 13:39:51 +08:00
|
|
|
import { Connection, ConnectionRawMessage } from '~/types'
|
2023-09-08 11:22:16 +08:00
|
|
|
|
2023-09-08 18:42:15 +08:00
|
|
|
export type WsMsg = {
|
2023-09-15 13:37:11 +08:00
|
|
|
connections?: ConnectionRawMessage[]
|
2023-09-08 11:22:16 +08:00
|
|
|
uploadTotal: number
|
|
|
|
downloadTotal: number
|
|
|
|
} | null
|
|
|
|
|
2023-09-08 11:55:22 +08:00
|
|
|
// we make connections global, so we can keep track of connections when user in proxy page
|
2023-09-08 11:22:16 +08:00
|
|
|
// when user selects proxy and close some connections they can back and check connections
|
|
|
|
// they closed
|
2023-09-09 03:49:29 +08:00
|
|
|
export let allConnections: Connection[] = []
|
2023-09-08 18:42:15 +08:00
|
|
|
|
|
|
|
export const setAllConnections = (allConns: Connection[]) => {
|
2023-09-08 15:35:06 +08:00
|
|
|
allConnections = allConns
|
|
|
|
}
|
2023-09-08 11:22:16 +08:00
|
|
|
|
2023-09-08 13:39:51 +08:00
|
|
|
export let latestConnectionMsg: Accessor<WsMsg> = () => ({
|
2023-09-08 11:35:53 +08:00
|
|
|
uploadTotal: 0,
|
|
|
|
downloadTotal: 0,
|
|
|
|
connections: [],
|
2023-09-08 11:22:16 +08:00
|
|
|
})
|
|
|
|
|
2023-09-08 18:42:15 +08:00
|
|
|
export const setLatestConnectionMsg = (accessor: Accessor<WsMsg>) => {
|
|
|
|
latestConnectionMsg = accessor
|
|
|
|
}
|
2023-09-08 11:22:16 +08:00
|
|
|
|
|
|
|
export const useConnections = () => {
|
2023-09-08 13:39:51 +08:00
|
|
|
const [closedConnections, setClosedConnections] = createSignal<Connection[]>(
|
|
|
|
[],
|
|
|
|
)
|
|
|
|
const [activeConnections, setActiveConnections] = createSignal<Connection[]>(
|
|
|
|
[],
|
|
|
|
)
|
2023-09-08 11:22:16 +08:00
|
|
|
const [paused, setPaused] = createSignal(false)
|
|
|
|
|
|
|
|
createEffect(() => {
|
2023-09-08 13:39:51 +08:00
|
|
|
const rawConns = latestConnectionMsg()?.connections
|
2023-09-08 11:22:16 +08:00
|
|
|
|
2023-09-08 13:39:51 +08:00
|
|
|
if (!rawConns) {
|
2023-09-08 11:22:16 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
untrack(() => {
|
2023-09-08 13:39:51 +08:00
|
|
|
const activeConns = restructRawMsgToConnection(
|
|
|
|
rawConns,
|
|
|
|
activeConnections(),
|
|
|
|
)
|
|
|
|
const allConns = mergeAllConnections(activeConns)
|
2023-09-08 11:22:16 +08:00
|
|
|
|
|
|
|
if (!paused()) {
|
2023-09-08 13:39:51 +08:00
|
|
|
const closedConns = diffClosedConnections(activeConns, allConns)
|
|
|
|
|
2023-09-10 18:47:01 +08:00
|
|
|
setActiveConnections(activeConns)
|
|
|
|
setClosedConnections(
|
|
|
|
closedConns.slice(-CONNECTIONS_TABLE_MAX_CLOSED_ROWS),
|
|
|
|
)
|
2023-09-08 11:22:16 +08:00
|
|
|
}
|
|
|
|
|
2023-09-10 18:47:01 +08:00
|
|
|
setAllConnections(
|
|
|
|
allConns.slice(
|
|
|
|
-(activeConns.length + CONNECTIONS_TABLE_MAX_CLOSED_ROWS),
|
|
|
|
),
|
|
|
|
)
|
2023-09-08 11:22:16 +08:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
return {
|
2023-09-08 13:39:51 +08:00
|
|
|
closedConnections,
|
|
|
|
activeConnections,
|
2023-09-08 11:22:16 +08:00
|
|
|
paused,
|
|
|
|
setPaused,
|
|
|
|
}
|
|
|
|
}
|
2023-09-08 13:39:51 +08:00
|
|
|
|
2023-09-08 17:09:32 +08:00
|
|
|
export const restructRawMsgToConnection = (
|
2023-09-08 13:39:51 +08:00
|
|
|
connections: ConnectionRawMessage[],
|
|
|
|
prevActiveConnections: Connection[],
|
2023-09-08 17:09:32 +08:00
|
|
|
): Connection[] => {
|
2023-09-08 13:39:51 +08:00
|
|
|
const prevMap = new Map<string, Connection>()
|
|
|
|
prevActiveConnections.forEach((prev) => prevMap.set(prev.id, prev))
|
|
|
|
|
|
|
|
return connections.map((connection) => {
|
|
|
|
const prevConn = prevMap.get(connection.id)
|
|
|
|
|
|
|
|
if (
|
|
|
|
!prevConn ||
|
|
|
|
!isNumber(prevConn.download) ||
|
|
|
|
!isNumber(prevConn.upload)
|
|
|
|
) {
|
|
|
|
return { ...connection, downloadSpeed: 0, uploadSpeed: 0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...connection,
|
|
|
|
downloadSpeed: connection.download - prevConn.download,
|
|
|
|
uploadSpeed: connection.upload - prevConn.upload,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-09-08 17:09:32 +08:00
|
|
|
export const mergeAllConnections = (activeConns: Connection[]) => {
|
2023-09-08 15:35:06 +08:00
|
|
|
return unionWith(allConnections, activeConns, (a, b) => a.id === b.id)
|
2023-09-08 13:39:51 +08:00
|
|
|
}
|
|
|
|
|
2023-09-08 17:09:32 +08:00
|
|
|
const diffClosedConnections = (
|
2023-09-08 13:39:51 +08:00
|
|
|
activeConns: Connection[],
|
|
|
|
allConns: Connection[],
|
2023-09-08 17:09:32 +08:00
|
|
|
) => {
|
2023-09-08 13:39:51 +08:00
|
|
|
return differenceWith(allConns, activeConns, (a, b) => a.id === b.id)
|
|
|
|
}
|