mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-12-27 07:34:12 +08:00
fix: latency not correct when set custom url in config (#1189)
To thoroughly fix this issue, all latency-related logic needs to be strongly bound to testurl
This commit is contained in:
parent
f610333717
commit
af3081371d
@ -1,17 +1,23 @@
|
|||||||
import { JSX, ParentComponent } from 'solid-js'
|
import { JSX, ParentComponent } from 'solid-js'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
import { getLatencyClassName } from '~/helpers'
|
import { getLatencyClassName } from '~/helpers'
|
||||||
import { useProxies } from '~/signals'
|
import { urlForLatencyTest, useProxies } from '~/signals'
|
||||||
|
|
||||||
interface Props extends JSX.HTMLAttributes<HTMLSpanElement> {
|
interface Props extends JSX.HTMLAttributes<HTMLSpanElement> {
|
||||||
proxyName: string
|
proxyName: string
|
||||||
|
testUrl: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Latency: ParentComponent<Props> = (props) => {
|
export const Latency: ParentComponent<Props> = (props) => {
|
||||||
const [local, others] = splitProps(props, ['class'])
|
const [local, others] = splitProps(props, ['class'])
|
||||||
const { getLatencyByName } = useProxies()
|
const { getLatencyByName } = useProxies()
|
||||||
const [textClassName, setTextClassName] = createSignal('')
|
const [textClassName, setTextClassName] = createSignal('')
|
||||||
const latency = createMemo(() => getLatencyByName(others.proxyName || ''))
|
const latency = createMemo(() =>
|
||||||
|
getLatencyByName(
|
||||||
|
others.proxyName || '',
|
||||||
|
others.testUrl || urlForLatencyTest(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
setTextClassName(getLatencyClassName(latency()))
|
setTextClassName(getLatencyClassName(latency()))
|
||||||
@ -19,7 +25,11 @@ export const Latency: ParentComponent<Props> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
class={twMerge('badge w-11 whitespace-nowrap', textClassName(), local.class)}
|
class={twMerge(
|
||||||
|
'badge w-11 whitespace-nowrap',
|
||||||
|
textClassName(),
|
||||||
|
local.class,
|
||||||
|
)}
|
||||||
{...others}
|
{...others}
|
||||||
>
|
>
|
||||||
{latency() || '---'}
|
{latency() || '---'}
|
||||||
|
@ -8,10 +8,12 @@ import {
|
|||||||
formatProxyType,
|
formatProxyType,
|
||||||
getLatencyClassName,
|
getLatencyClassName,
|
||||||
} from '~/helpers'
|
} from '~/helpers'
|
||||||
import { rootElement, useProxies } from '~/signals'
|
import { rootElement, urlForLatencyTest, useProxies } from '~/signals'
|
||||||
|
|
||||||
export const ProxyNodeCard = (props: {
|
export const ProxyNodeCard = (props: {
|
||||||
proxyName: string
|
proxyName: string
|
||||||
|
testUrl: string | null
|
||||||
|
timeout: number | null
|
||||||
isSelected?: boolean
|
isSelected?: boolean
|
||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
}) => {
|
}) => {
|
||||||
@ -36,6 +38,9 @@ export const ProxyNodeCard = (props: {
|
|||||||
[proxyName, specialTypes()].filter(Boolean).join(' - '),
|
[proxyName, specialTypes()].filter(Boolean).join(' - '),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const latencyTestHistory =
|
||||||
|
proxyNode().latencyTestHistory[props.testUrl || urlForLatencyTest()] || []
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
placement="top"
|
placement="top"
|
||||||
@ -67,13 +72,19 @@ export const ProxyNodeCard = (props: {
|
|||||||
|
|
||||||
<Latency
|
<Latency
|
||||||
proxyName={props.proxyName}
|
proxyName={props.proxyName}
|
||||||
|
testUrl={props.testUrl || null}
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
proxyLatencyTestingMap()[proxyName] && 'animate-pulse',
|
proxyLatencyTestingMap()[proxyName] && 'animate-pulse',
|
||||||
)}
|
)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
|
||||||
void proxyLatencyTest(proxyName, proxyNode().provider)
|
void proxyLatencyTest(
|
||||||
|
proxyName,
|
||||||
|
proxyNode().provider,
|
||||||
|
props.testUrl,
|
||||||
|
props.timeout,
|
||||||
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -87,12 +98,10 @@ export const ProxyNodeCard = (props: {
|
|||||||
<div class="flex flex-col items-center gap-2 rounded-box bg-neutral bg-gradient-to-br from-primary to-secondary p-2.5 text-primary-content shadow-lg">
|
<div class="flex flex-col items-center gap-2 rounded-box bg-neutral bg-gradient-to-br from-primary to-secondary p-2.5 text-primary-content shadow-lg">
|
||||||
<h2 class="text-lg font-bold">{proxyName}</h2>
|
<h2 class="text-lg font-bold">{proxyName}</h2>
|
||||||
|
|
||||||
<div class="w-full text-xs uppercase">
|
<div class="w-full text-xs uppercase">{specialTypes()}</div>
|
||||||
{specialTypes()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="timeline timeline-vertical timeline-compact timeline-snap-icon">
|
<ul class="timeline timeline-vertical timeline-compact timeline-snap-icon">
|
||||||
<For each={proxyNode().latencyTestHistory}>
|
<For each={latencyTestHistory}>
|
||||||
{(latencyTestResult, index) => (
|
{(latencyTestResult, index) => (
|
||||||
<li>
|
<li>
|
||||||
<Show when={index() > 0}>
|
<Show when={index() > 0}>
|
||||||
@ -120,11 +129,7 @@ export const ProxyNodeCard = (props: {
|
|||||||
<IconCircleCheckFilled class="size-4" />
|
<IconCircleCheckFilled class="size-4" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show
|
<Show when={index() !== latencyTestHistory.length - 1}>
|
||||||
when={
|
|
||||||
index() !== proxyNode().latencyTestHistory.length - 1
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<hr />
|
<hr />
|
||||||
</Show>
|
</Show>
|
||||||
</li>
|
</li>
|
||||||
|
@ -4,6 +4,7 @@ import { proxiesPreviewType } from '~/signals'
|
|||||||
|
|
||||||
export const ProxyNodePreview = (props: {
|
export const ProxyNodePreview = (props: {
|
||||||
proxyNameList: string[]
|
proxyNameList: string[]
|
||||||
|
testUrl: string | null
|
||||||
now?: string
|
now?: string
|
||||||
}) => {
|
}) => {
|
||||||
const off = () => proxiesPreviewType() === PROXIES_PREVIEW_TYPE.OFF
|
const off = () => proxiesPreviewType() === PROXIES_PREVIEW_TYPE.OFF
|
||||||
@ -34,6 +35,7 @@ export const ProxyNodePreview = (props: {
|
|||||||
<Match when={isShowBar()}>
|
<Match when={isShowBar()}>
|
||||||
<ProxyPreviewBar
|
<ProxyPreviewBar
|
||||||
proxyNameList={props.proxyNameList}
|
proxyNameList={props.proxyNameList}
|
||||||
|
testUrl={props.testUrl}
|
||||||
now={props.now}
|
now={props.now}
|
||||||
/>
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
@ -41,6 +43,7 @@ export const ProxyNodePreview = (props: {
|
|||||||
<Match when={isShowDots()}>
|
<Match when={isShowDots()}>
|
||||||
<ProxyPreviewDots
|
<ProxyPreviewDots
|
||||||
proxyNameList={props.proxyNameList}
|
proxyNameList={props.proxyNameList}
|
||||||
|
testUrl={props.testUrl}
|
||||||
now={props.now}
|
now={props.now}
|
||||||
/>
|
/>
|
||||||
</Match>
|
</Match>
|
||||||
|
@ -3,11 +3,12 @@ import { latencyQualityMap, useProxies } from '~/signals'
|
|||||||
|
|
||||||
export const ProxyPreviewBar = (props: {
|
export const ProxyPreviewBar = (props: {
|
||||||
proxyNameList: string[]
|
proxyNameList: string[]
|
||||||
|
testUrl: string | null
|
||||||
now?: string
|
now?: string
|
||||||
}) => {
|
}) => {
|
||||||
const { getLatencyByName } = useProxies()
|
const { getLatencyByName } = useProxies()
|
||||||
const latencyList = createMemo(() =>
|
const latencyList = createMemo(() =>
|
||||||
props.proxyNameList.map((name) => getLatencyByName(name)),
|
props.proxyNameList.map((name) => getLatencyByName(name, props.testUrl)),
|
||||||
)
|
)
|
||||||
|
|
||||||
const all = createMemo(() => latencyList().length)
|
const all = createMemo(() => latencyList().length)
|
||||||
@ -69,7 +70,7 @@ export const ProxyPreviewBar = (props: {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={props.now}>
|
<Show when={props.now}>
|
||||||
<Latency proxyName={props.now!} />
|
<Latency proxyName={props.now!} testUrl={props.testUrl} />
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -38,6 +38,7 @@ const LatencyDot = (props: {
|
|||||||
|
|
||||||
export const ProxyPreviewDots = (props: {
|
export const ProxyPreviewDots = (props: {
|
||||||
proxyNameList: string[]
|
proxyNameList: string[]
|
||||||
|
testUrl: string | null
|
||||||
now?: string
|
now?: string
|
||||||
}) => {
|
}) => {
|
||||||
const { getLatencyByName } = useProxies()
|
const { getLatencyByName } = useProxies()
|
||||||
@ -48,7 +49,7 @@ export const ProxyPreviewDots = (props: {
|
|||||||
<For
|
<For
|
||||||
each={props.proxyNameList.map((name): [string, number] => [
|
each={props.proxyNameList.map((name): [string, number] => [
|
||||||
name,
|
name,
|
||||||
getLatencyByName(name),
|
getLatencyByName(name, props.testUrl),
|
||||||
])}
|
])}
|
||||||
>
|
>
|
||||||
{([name, latency]) => (
|
{([name, latency]) => (
|
||||||
@ -62,7 +63,7 @@ export const ProxyPreviewDots = (props: {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={props.now}>
|
<Show when={props.now}>
|
||||||
<Latency proxyName={props.now!} />
|
<Latency proxyName={props.now!} testUrl={props.testUrl} />
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { LATENCY_QUALITY_MAP_HTTP, PROXIES_ORDERING_TYPE } from '~/constants'
|
import { LATENCY_QUALITY_MAP_HTTP, PROXIES_ORDERING_TYPE } from '~/constants'
|
||||||
import { useI18n } from '~/i18n'
|
import { useI18n } from '~/i18n'
|
||||||
import { latencyQualityMap, useProxies } from '~/signals'
|
import { latencyQualityMap, urlForLatencyTest, useProxies } from '~/signals'
|
||||||
|
|
||||||
export const formatProxyType = (type = '') => {
|
export const formatProxyType = (type = '') => {
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
@ -55,19 +55,26 @@ export const filterSpecialProxyType = (type = '') => {
|
|||||||
return !conditions.includes(type.toLowerCase())
|
return !conditions.includes(type.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sortProxiesByOrderingType = (
|
export const sortProxiesByOrderingType = ({
|
||||||
proxyNames: string[],
|
proxyNames,
|
||||||
orderingType: PROXIES_ORDERING_TYPE,
|
orderingType,
|
||||||
) => {
|
testUrl,
|
||||||
|
}: {
|
||||||
|
proxyNames: string[]
|
||||||
|
orderingType: PROXIES_ORDERING_TYPE
|
||||||
|
testUrl: string | null
|
||||||
|
}) => {
|
||||||
const { getLatencyByName } = useProxies()
|
const { getLatencyByName } = useProxies()
|
||||||
|
|
||||||
if (orderingType === PROXIES_ORDERING_TYPE.NATURAL) {
|
if (orderingType === PROXIES_ORDERING_TYPE.NATURAL) {
|
||||||
return proxyNames
|
return proxyNames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const finalTestUrl = testUrl || urlForLatencyTest()
|
||||||
|
|
||||||
return proxyNames.sort((a, b) => {
|
return proxyNames.sort((a, b) => {
|
||||||
const prevLatency = getLatencyByName(a)
|
const prevLatency = getLatencyByName(a, finalTestUrl)
|
||||||
const nextLatency = getLatencyByName(b)
|
const nextLatency = getLatencyByName(b, finalTestUrl)
|
||||||
|
|
||||||
switch (orderingType) {
|
switch (orderingType) {
|
||||||
case PROXIES_ORDERING_TYPE.LATENCY_ASC:
|
case PROXIES_ORDERING_TYPE.LATENCY_ASC:
|
||||||
@ -96,19 +103,27 @@ export const sortProxiesByOrderingType = (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const filterProxiesByAvailability = (
|
export const filterProxiesByAvailability = ({
|
||||||
proxyNames: string[],
|
proxyNames,
|
||||||
enabled?: boolean,
|
enabled,
|
||||||
) => {
|
testUrl,
|
||||||
|
}: {
|
||||||
|
proxyNames: string[]
|
||||||
|
enabled?: boolean
|
||||||
|
testUrl: string | null
|
||||||
|
}) => {
|
||||||
const { getLatencyByName, isProxyGroup } = useProxies()
|
const { getLatencyByName, isProxyGroup } = useProxies()
|
||||||
|
|
||||||
|
const finalTestUrl = testUrl || urlForLatencyTest()
|
||||||
|
|
||||||
return enabled
|
return enabled
|
||||||
? proxyNames.filter(
|
? proxyNames.filter(
|
||||||
// we need proxy node with connected or the node is a group it self
|
// we need proxy node with connected or the node is a group it self
|
||||||
(name) => {
|
(name) => {
|
||||||
return (
|
return (
|
||||||
isProxyGroup(name) ||
|
isProxyGroup(name) ||
|
||||||
getLatencyByName(name) !== latencyQualityMap().NOT_CONNECTED
|
getLatencyByName(name, finalTestUrl) !==
|
||||||
|
latencyQualityMap().NOT_CONNECTED
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -198,13 +198,15 @@ export default () => {
|
|||||||
<For each={renderProxies()}>
|
<For each={renderProxies()}>
|
||||||
{(proxyGroup) => {
|
{(proxyGroup) => {
|
||||||
const sortedProxyNames = createMemo(() =>
|
const sortedProxyNames = createMemo(() =>
|
||||||
filterProxiesByAvailability(
|
filterProxiesByAvailability({
|
||||||
sortProxiesByOrderingType(
|
proxyNames: sortProxiesByOrderingType({
|
||||||
proxyGroup.all ?? [],
|
proxyNames: proxyGroup.all ?? [],
|
||||||
proxiesOrderingType(),
|
orderingType: proxiesOrderingType(),
|
||||||
),
|
testUrl: proxyGroup.testUrl || null,
|
||||||
hideUnAvailableProxies(),
|
}),
|
||||||
),
|
enabled: hideUnAvailableProxies(),
|
||||||
|
testUrl: proxyGroup.testUrl || null,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const title = (
|
const title = (
|
||||||
@ -291,6 +293,7 @@ export default () => {
|
|||||||
<ProxyNodePreview
|
<ProxyNodePreview
|
||||||
proxyNameList={sortedProxyNames()}
|
proxyNameList={sortedProxyNames()}
|
||||||
now={proxyGroup.now}
|
now={proxyGroup.now}
|
||||||
|
testUrl={proxyGroup.testUrl || null}
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
@ -308,6 +311,8 @@ export default () => {
|
|||||||
{(proxyName) => (
|
{(proxyName) => (
|
||||||
<ProxyNodeCard
|
<ProxyNodeCard
|
||||||
proxyName={proxyName}
|
proxyName={proxyName}
|
||||||
|
testUrl={proxyGroup.testUrl || null}
|
||||||
|
timeout={proxyGroup.timeout ?? null}
|
||||||
isSelected={proxyGroup.now === proxyName}
|
isSelected={proxyGroup.now === proxyName}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
void selectProxyInGroup(proxyGroup, proxyName)
|
void selectProxyInGroup(proxyGroup, proxyName)
|
||||||
@ -327,10 +332,12 @@ export default () => {
|
|||||||
<For each={proxyProviders()}>
|
<For each={proxyProviders()}>
|
||||||
{(proxyProvider) => {
|
{(proxyProvider) => {
|
||||||
const sortedProxyNames = createMemo(() =>
|
const sortedProxyNames = createMemo(() =>
|
||||||
sortProxiesByOrderingType(
|
sortProxiesByOrderingType({
|
||||||
|
orderingType: proxiesOrderingType(),
|
||||||
|
proxyNames:
|
||||||
proxyProvider.proxies.map((i) => i.name) ?? [],
|
proxyProvider.proxies.map((i) => i.name) ?? [],
|
||||||
proxiesOrderingType(),
|
testUrl: proxyProvider.testUrl,
|
||||||
),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const title = (
|
const title = (
|
||||||
@ -397,7 +404,10 @@ export default () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={!collapsedMap()[proxyProvider.name]}>
|
<Show when={!collapsedMap()[proxyProvider.name]}>
|
||||||
<ProxyNodePreview proxyNameList={sortedProxyNames()} />
|
<ProxyNodePreview
|
||||||
|
proxyNameList={sortedProxyNames()}
|
||||||
|
testUrl={proxyProvider.testUrl}
|
||||||
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
@ -411,7 +421,13 @@ export default () => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<For each={sortedProxyNames()}>
|
<For each={sortedProxyNames()}>
|
||||||
{(proxyName) => <ProxyNodeCard proxyName={proxyName} />}
|
{(proxyName) => (
|
||||||
|
<ProxyNodeCard
|
||||||
|
proxyName={proxyName}
|
||||||
|
testUrl={proxyProvider.testUrl}
|
||||||
|
timeout={proxyProvider.timeout ?? null}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</For>
|
</For>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
)
|
)
|
||||||
|
@ -23,10 +23,7 @@ type ProxyInfo = {
|
|||||||
name: string
|
name: string
|
||||||
udp: boolean
|
udp: boolean
|
||||||
tfo: boolean
|
tfo: boolean
|
||||||
latencyTestHistory: {
|
latencyTestHistory: Record<string, Proxy['history'] | undefined>
|
||||||
time: string
|
|
||||||
delay: number
|
|
||||||
}[]
|
|
||||||
latency: string
|
latency: string
|
||||||
xudp: boolean
|
xudp: boolean
|
||||||
type: string
|
type: string
|
||||||
@ -59,31 +56,61 @@ const [proxyProviders, setProxyProviders] = createSignal<
|
|||||||
>([])
|
>([])
|
||||||
|
|
||||||
// DO NOT use latency from latency map directly use getLatencyByName instead
|
// DO NOT use latency from latency map directly use getLatencyByName instead
|
||||||
const [latencyMap, setLatencyMap] = createSignal<Record<string, number>>({})
|
const [latencyMap, setLatencyMap] = createSignal<
|
||||||
|
Record<string, Record<string, number> | undefined>
|
||||||
|
>({})
|
||||||
|
|
||||||
const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
const [proxyNodeMap, setProxyNodeMap] = createSignal<Record<string, ProxyInfo>>(
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AllTestUrlLatencyInfo = {
|
||||||
|
allTestUrlLatency: Record<string, number>
|
||||||
|
allTestUrlLatencyHistory: Record<string, Proxy['history'] | undefined>
|
||||||
|
}
|
||||||
|
|
||||||
const getLatencyFromProxy = (
|
const getLatencyFromProxy = (
|
||||||
proxy: Pick<Proxy, 'extra' | 'history'>,
|
proxy: Pick<Proxy, 'extra' | 'history'>,
|
||||||
url: string,
|
|
||||||
fallbackDefault = true,
|
fallbackDefault = true,
|
||||||
) => {
|
): AllTestUrlLatencyInfo => {
|
||||||
const extra = proxy.extra?.[url] as Proxy['history'] | undefined
|
const extra = (proxy.extra || {}) as Record<
|
||||||
|
string,
|
||||||
if (Array.isArray(extra)) {
|
{
|
||||||
const delay = extra.at(-1)?.delay
|
history?: Proxy['history']
|
||||||
|
|
||||||
if (delay) {
|
|
||||||
return delay
|
|
||||||
}
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
if (!Object.keys(extra).length && fallbackDefault) {
|
||||||
|
const testUrl = urlForLatencyTest()
|
||||||
|
|
||||||
|
const delay =
|
||||||
|
proxy.history?.at(-1)?.delay ?? latencyQualityMap().NOT_CONNECTED
|
||||||
|
|
||||||
|
const allTestUrlLatency = { [testUrl]: delay }
|
||||||
|
const allTestUrlLatencyHistory = { [testUrl]: proxy.history }
|
||||||
|
|
||||||
|
return {
|
||||||
|
allTestUrlLatency,
|
||||||
|
allTestUrlLatencyHistory,
|
||||||
|
} as AllTestUrlLatencyInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fallbackDefault) {
|
return Object.keys(extra).reduce(
|
||||||
return latencyQualityMap().NOT_CONNECTED
|
(acc, testUrl) => {
|
||||||
}
|
const data = extra[testUrl]
|
||||||
|
const delay =
|
||||||
|
data?.history?.at(-1)?.delay ?? latencyQualityMap().NOT_CONNECTED
|
||||||
|
|
||||||
return proxy.history?.at(-1)?.delay ?? latencyQualityMap().NOT_CONNECTED
|
acc.allTestUrlLatency[testUrl] = delay
|
||||||
|
acc.allTestUrlLatencyHistory[testUrl] = data.history
|
||||||
|
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allTestUrlLatency: {},
|
||||||
|
allTestUrlLatencyHistory: {},
|
||||||
|
} as AllTestUrlLatencyInfo,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setProxiesInfo = (
|
const setProxiesInfo = (
|
||||||
@ -93,20 +120,23 @@ const setProxiesInfo = (
|
|||||||
const newLatencyMap = { ...latencyMap() }
|
const newLatencyMap = { ...latencyMap() }
|
||||||
|
|
||||||
proxies.forEach((proxy) => {
|
proxies.forEach((proxy) => {
|
||||||
const { udp, xudp, type, now, history, name, tfo, provider = '' } = proxy
|
const { allTestUrlLatency, allTestUrlLatencyHistory } =
|
||||||
|
getLatencyFromProxy(proxy)
|
||||||
|
|
||||||
|
const { udp, xudp, type, now, name, tfo, provider = '' } = proxy
|
||||||
|
|
||||||
newProxyNodeMap[proxy.name] = {
|
newProxyNodeMap[proxy.name] = {
|
||||||
udp,
|
udp,
|
||||||
xudp,
|
xudp,
|
||||||
type,
|
type,
|
||||||
latency: now,
|
latency: now,
|
||||||
latencyTestHistory: history,
|
latencyTestHistory: allTestUrlLatencyHistory,
|
||||||
name,
|
name,
|
||||||
tfo,
|
tfo,
|
||||||
provider,
|
provider,
|
||||||
}
|
}
|
||||||
|
|
||||||
newLatencyMap[proxy.name] = getLatencyFromProxy(proxy, urlForLatencyTest())
|
newLatencyMap[proxy.name] = allTestUrlLatency
|
||||||
})
|
})
|
||||||
|
|
||||||
batch(() => {
|
batch(() => {
|
||||||
@ -122,8 +152,18 @@ export const useProxies = () => {
|
|||||||
fetchProxiesAPI(),
|
fetchProxiesAPI(),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const proxiesWithTestUrl = Object.values(proxies).map((proxy) => {
|
||||||
|
if (proxy.all?.length) {
|
||||||
|
const { testUrl, timeout } = providers?.[proxy.name] || {}
|
||||||
|
|
||||||
|
return { ...proxy, testUrl, timeout }
|
||||||
|
} else {
|
||||||
|
return proxy
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const sortIndex = [...(proxies['GLOBAL'].all ?? []), 'GLOBAL']
|
const sortIndex = [...(proxies['GLOBAL'].all ?? []), 'GLOBAL']
|
||||||
const sortedProxies = Object.values(proxies)
|
const sortedProxies = Object.values(proxiesWithTestUrl)
|
||||||
.filter((proxy) => proxy.all?.length)
|
.filter((proxy) => proxy.all?.length)
|
||||||
.sort(
|
.sort(
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
@ -135,7 +175,7 @@ export const useProxies = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const allProxies = [
|
const allProxies = [
|
||||||
...Object.values(proxies),
|
...proxiesWithTestUrl,
|
||||||
...sortedProviders.flatMap((provider) =>
|
...sortedProviders.flatMap((provider) =>
|
||||||
provider.proxies
|
provider.proxies
|
||||||
.filter((proxy) => !(proxy.name in proxies))
|
.filter((proxy) => !(proxy.name in proxies))
|
||||||
@ -177,37 +217,53 @@ export const useProxies = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const proxyLatencyTest = async (proxyName: string, provider: string) => {
|
const proxyLatencyTest = async (
|
||||||
|
proxyName: string,
|
||||||
|
provider: string,
|
||||||
|
testUrl: string | null,
|
||||||
|
timmeout: number | null,
|
||||||
|
) => {
|
||||||
const nodeName = getNowProxyNodeName(proxyName)
|
const nodeName = getNowProxyNodeName(proxyName)
|
||||||
|
|
||||||
setProxyLatencyTestingMap(nodeName, async () => {
|
setProxyLatencyTestingMap(nodeName, async () => {
|
||||||
|
const finalTestUrl = testUrl || urlForLatencyTest()
|
||||||
|
const currentNodeLatency = latencyMap()?.[nodeName] || {}
|
||||||
try {
|
try {
|
||||||
const { delay } = await proxyLatencyTestAPI(
|
const { delay } = await proxyLatencyTestAPI(
|
||||||
nodeName,
|
nodeName,
|
||||||
provider,
|
provider,
|
||||||
urlForLatencyTest(),
|
finalTestUrl,
|
||||||
latencyTestTimeoutDuration(),
|
timmeout ?? latencyTestTimeoutDuration(),
|
||||||
)
|
)
|
||||||
|
|
||||||
setLatencyMap((latencyMap) => ({
|
currentNodeLatency[finalTestUrl] = delay
|
||||||
|
|
||||||
|
setLatencyMap((latencyMap) => {
|
||||||
|
return {
|
||||||
...latencyMap,
|
...latencyMap,
|
||||||
[nodeName]: delay,
|
[nodeName]: currentNodeLatency,
|
||||||
}))
|
}
|
||||||
|
})
|
||||||
} catch {
|
} catch {
|
||||||
|
currentNodeLatency[finalTestUrl] = latencyQualityMap().NOT_CONNECTED
|
||||||
setLatencyMap((latencyMap) => ({
|
setLatencyMap((latencyMap) => ({
|
||||||
...latencyMap,
|
...latencyMap,
|
||||||
[nodeName]: latencyQualityMap().NOT_CONNECTED,
|
[nodeName]: currentNodeLatency,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const proxyGroupLatencyTest = async (proxyGroupName: string) => {
|
const proxyGroupLatencyTest = async (proxyGroupName: string) => {
|
||||||
|
const currentProxyGroups = proxies()
|
||||||
setProxyGroupLatencyTestingMap(proxyGroupName, async () => {
|
setProxyGroupLatencyTestingMap(proxyGroupName, async () => {
|
||||||
|
const currentProxyGroup = currentProxyGroups.find(
|
||||||
|
(item) => item.name === proxyGroupName,
|
||||||
|
)
|
||||||
await proxyGroupLatencyTestAPI(
|
await proxyGroupLatencyTestAPI(
|
||||||
proxyGroupName,
|
proxyGroupName,
|
||||||
urlForLatencyTest(),
|
currentProxyGroup?.testUrl || urlForLatencyTest(),
|
||||||
latencyTestTimeoutDuration(),
|
currentProxyGroup?.timeout ?? latencyTestTimeoutDuration(),
|
||||||
)
|
)
|
||||||
await fetchProxies()
|
await fetchProxies()
|
||||||
})
|
})
|
||||||
@ -263,8 +319,10 @@ export const useProxies = () => {
|
|||||||
return node.name
|
return node.name
|
||||||
}
|
}
|
||||||
|
|
||||||
const getLatencyByName = (name: string) => {
|
const getLatencyByName = (name: string, testUrl: string | null) => {
|
||||||
return latencyMap()[getNowProxyNodeName(name)]
|
const finalTestUrl = testUrl || urlForLatencyTest()
|
||||||
|
|
||||||
|
return latencyMap()[getNowProxyNodeName(name)]?.[finalTestUrl] || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const isProxyGroup = (name: string) => {
|
const isProxyGroup = (name: string) => {
|
||||||
|
3
src/types/index.d.ts
vendored
3
src/types/index.d.ts
vendored
@ -23,6 +23,8 @@ export type Proxy = {
|
|||||||
xudp: boolean
|
xudp: boolean
|
||||||
tfo: boolean
|
tfo: boolean
|
||||||
now: string
|
now: string
|
||||||
|
testUrl?: string
|
||||||
|
timeout?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProxyNode = {
|
export type ProxyNode = {
|
||||||
@ -53,6 +55,7 @@ export type ProxyProvider = {
|
|||||||
name: string
|
name: string
|
||||||
proxies: ProxyNode[]
|
proxies: ProxyNode[]
|
||||||
testUrl: string
|
testUrl: string
|
||||||
|
timeout?: number
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
vehicleType: string
|
vehicleType: string
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user