2023-09-08 11:22:16 +08:00
|
|
|
import { differenceWith, unionWith } from 'lodash'
|
2023-09-08 11:35:53 +08:00
|
|
|
import { Accessor, createEffect, createSignal, untrack } from 'solid-js'
|
2023-09-08 11:22:16 +08:00
|
|
|
import { Connection, ConnectionWithSpeed } from '~/types'
|
|
|
|
import { selectedEndpoint, useWsRequest } from './request'
|
|
|
|
|
|
|
|
type WsMsg = {
|
|
|
|
connections: Connection[]
|
|
|
|
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
|
|
|
|
const [allConnectionsWithSpeed, setAllConnectionsWithSpeed] = createSignal<
|
|
|
|
ConnectionWithSpeed[]
|
|
|
|
>([])
|
|
|
|
|
2023-09-08 11:35:53 +08:00
|
|
|
export let connections: Accessor<WsMsg> = () => ({
|
|
|
|
uploadTotal: 0,
|
|
|
|
downloadTotal: 0,
|
|
|
|
connections: [],
|
2023-09-08 11:22:16 +08:00
|
|
|
})
|
|
|
|
|
2023-09-08 11:35:53 +08:00
|
|
|
createEffect(() => {
|
|
|
|
if (selectedEndpoint()) {
|
|
|
|
connections = useWsRequest<WsMsg>('connections')
|
|
|
|
}
|
|
|
|
})
|
2023-09-08 11:22:16 +08:00
|
|
|
|
|
|
|
export const useConnections = () => {
|
|
|
|
const [closedConnectionsWithSpeed, setClosedConnectionsWithSpeed] =
|
|
|
|
createSignal<ConnectionWithSpeed[]>([])
|
|
|
|
const [activeConnectionsWithSpeed, setActiveConnectionsWithSpeed] =
|
|
|
|
createSignal<ConnectionWithSpeed[]>([])
|
|
|
|
const [paused, setPaused] = createSignal(false)
|
|
|
|
|
|
|
|
const updateConnectionsWithSpeed = (connections: Connection[]) => {
|
|
|
|
const prevActiveConnections = activeConnectionsWithSpeed()
|
|
|
|
const prevMap = new Map<string, Connection>()
|
|
|
|
prevActiveConnections.forEach((prev) => prevMap.set(prev.id, prev))
|
|
|
|
|
2023-09-08 11:55:22 +08:00
|
|
|
const activeConnections: ConnectionWithSpeed[] = connections.map(
|
2023-09-08 11:22:16 +08:00
|
|
|
(connection) => {
|
|
|
|
const prevConn = prevMap.get(connection.id)
|
|
|
|
|
|
|
|
if (!prevConn) {
|
|
|
|
return { ...connection, downloadSpeed: 0, uploadSpeed: 0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...connection,
|
|
|
|
downloadSpeed:
|
|
|
|
connection.download - (prevConn.download ?? connection.download),
|
|
|
|
uploadSpeed:
|
|
|
|
connection.upload - (prevConn.upload ?? connection.upload),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
const allConnections = unionWith(
|
|
|
|
allConnectionsWithSpeed(),
|
2023-09-08 11:55:22 +08:00
|
|
|
activeConnections,
|
2023-09-08 11:22:16 +08:00
|
|
|
(a, b) => a.id === b.id,
|
|
|
|
)
|
|
|
|
const closedConnections = differenceWith(
|
|
|
|
allConnections,
|
2023-09-08 11:55:22 +08:00
|
|
|
activeConnections,
|
2023-09-08 11:22:16 +08:00
|
|
|
(a, b) => a.id === b.id,
|
|
|
|
)
|
|
|
|
|
|
|
|
return {
|
2023-09-08 11:55:22 +08:00
|
|
|
activeConns: activeConnections.slice(-200),
|
2023-09-08 11:22:16 +08:00
|
|
|
closedConns: closedConnections.slice(-200),
|
|
|
|
allConns: allConnections.slice(-400),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
createEffect(() => {
|
|
|
|
const connection = connections()?.connections
|
|
|
|
|
|
|
|
if (!connection) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
untrack(() => {
|
|
|
|
const { activeConns, closedConns, allConns } =
|
|
|
|
updateConnectionsWithSpeed(connection)
|
|
|
|
|
|
|
|
if (!paused()) {
|
|
|
|
setActiveConnectionsWithSpeed(activeConns)
|
|
|
|
setClosedConnectionsWithSpeed(closedConns)
|
|
|
|
}
|
|
|
|
|
|
|
|
setAllConnectionsWithSpeed(allConns)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
return {
|
|
|
|
closedConnectionsWithSpeed,
|
|
|
|
activeConnectionsWithSpeed,
|
|
|
|
paused,
|
|
|
|
setPaused,
|
|
|
|
}
|
|
|
|
}
|