Skip to content

Commit d24d845

Browse files
committed
refactor: improved WebSocket handling
1 parent 55b17f0 commit d24d845

File tree

40 files changed

+472
-544
lines changed

40 files changed

+472
-544
lines changed

app/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
"nprogress": "^0.2.0",
4444
"pinia": "^3.0.4",
4545
"pinia-plugin-persistedstate": "^4.7.1",
46-
"reconnecting-websocket": "^4.4.0",
4746
"sortablejs": "^1.15.6",
4847
"splitpanes": "^4.0.4",
4948
"sse.js": "^2.7.2",

app/src/api/analytic.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { http } from '@uozi-admin/request'
2-
import ws from '@/lib/websocket'
32

43
export interface CPUInfoStat {
54
cpu: number
@@ -120,12 +119,8 @@ const analytic = {
120119
init(): Promise<AnalyticInit> {
121120
return http.get('/analytic/init')
122121
},
123-
server() {
124-
return ws('/api/analytic')
125-
},
126-
nodes() {
127-
return ws('/api/analytic/nodes')
128-
},
122+
serverWebSocketUrl: '/api/analytic',
123+
nodesWebSocketUrl: '/api/analytic/nodes',
129124
}
130125

131126
export default analytic

app/src/api/llm.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type ReconnectingWebSocket from 'reconnecting-websocket'
21
import { http } from '@uozi-admin/request'
3-
import ws from '@/lib/websocket'
42

53
export interface ChatComplicationMessage {
64
role: string
@@ -41,9 +39,7 @@ const llm = {
4139
store_messages(data: { file_name?: string, messages?: ChatComplicationMessage[] }) {
4240
return http.post('/llm_messages', data)
4341
},
44-
code_completion() {
45-
return ws('/api/code_completion') as ReconnectingWebSocket
46-
},
42+
codeCompletionWebSocketUrl: '/api/code_completion',
4743
get_code_completion_enabled_status() {
4844
return http.get<{ enabled: boolean }>('/code_completion/enabled')
4945
},

app/src/api/node.ts

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,58 @@ export interface Node extends ModelBase {
55
name: string
66
url: string
77
token: string
8-
status?: boolean
9-
response_at?: Date
8+
status: boolean
9+
enabled: boolean
10+
response_at?: string
11+
}
12+
13+
export interface NodeStatus {
14+
avg_load: {
15+
load1: number
16+
load5: number
17+
load15: number
18+
}
19+
cpu_percent: number
20+
memory_percent: number
21+
disk_percent: number
22+
network: {
23+
name: string
24+
bytesSent: number
25+
bytesRecv: number
26+
packetsSent: number
27+
packetsRecv: number
28+
errin: number
29+
errout: number
30+
dropin: number
31+
dropout: number
32+
fifoin: number
33+
fifoout: number
34+
}
35+
status: boolean
36+
response_at?: string
37+
upstream_status_map: {
38+
[key: string]: {
39+
online: boolean
40+
latency: number
41+
}
42+
}
1043
}
1144

1245
export interface NodeInfo {
13-
id: number
14-
name: string
15-
token: string
16-
response_at?: Date
46+
node_runtime_info: {
47+
os: string
48+
arch: string
49+
ex_path: string
50+
cur_version: string
51+
in_docker: boolean
52+
}
53+
version: string
54+
cpu_num: number
55+
memory_total: string
56+
disk_total: string
57+
}
58+
59+
export interface AnalyticNode extends Node, NodeInfo, NodeStatus {
1760
}
1861

1962
const baseUrl = '/nodes'

app/src/api/self_check.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { Container } from '@/language'
22
import type { CosyError } from '@/lib/http'
33
import { http } from '@uozi-admin/request'
4-
import ws from '@/lib/websocket'
54

65
export const ReportStatus = {
76
Success: 'success',
@@ -27,9 +26,7 @@ const selfCheck = {
2726
fix(taskName: string) {
2827
return http.post(`/self_check/${taskName}/fix`)
2928
},
30-
websocket() {
31-
return ws('/api/self_check/websocket', false)
32-
},
29+
websocketUrl: '/api/self_check/websocket',
3330
timeoutCheck() {
3431
return http.get('/self_check/timeout')
3532
},

app/src/api/site_navigation.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { SiteStatusType } from '@/constants/site-status'
22
import { http } from '@uozi-admin/request'
3-
import ws from '@/lib/websocket'
43

54
export interface SiteInfo {
65
id: number // primary identifier for API operations
@@ -144,8 +143,6 @@ export const siteNavigationApi = {
144143
return http.post(`/site_navigation/test_health_check/${id}`, { config })
145144
},
146145

147-
// WebSocket connection using lib/websocket
148-
createWebSocket() {
149-
return ws('/api/site_navigation_ws', true)
150-
},
146+
// WebSocket URL for real-time updates
147+
websocketUrl: '/api/site_navigation_ws',
151148
}

app/src/api/upstream.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { http } from '@uozi-admin/request'
2-
import ws from '@/lib/websocket'
32

43
export interface UpstreamStatus {
54
online: boolean
@@ -45,10 +44,8 @@ const upstream = {
4544
return http.get('/upstream/availability')
4645
},
4746

48-
// WebSocket interface for real-time availability updates
49-
availabilityWebSocket() {
50-
return ws('/api/upstream/availability_ws')
51-
},
47+
// WebSocket URL for real-time availability updates
48+
availabilityWebSocketUrl: '/api/upstream/availability_ws',
5249

5350
// Get all sockets with their configuration and health status
5451
getSocketList(): Promise<SocketListResponse> {

app/src/components/CodeEditor/CodeCompletion.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { Editor } from 'ace-builds'
22
import type { Point } from 'ace-builds-internal/document'
3-
import type ReconnectingWebSocket from 'reconnecting-websocket'
43
import ace from 'ace-builds'
54
import { debounce } from 'lodash'
65
import { v4 as uuidv4 } from 'uuid'
76
import llm from '@/api/llm'
7+
import { useWebSocket } from '@/lib/websocket'
88

99
function debug(...args: unknown[]) {
1010
if (import.meta.env.DEV) {
@@ -43,7 +43,7 @@ function useCodeCompletion() {
4343
const lastTriggerTime = ref<number>(0)
4444
const lastTriggerPosition = ref<{ row: number, column: number } | null>(null)
4545

46-
const ws = shallowRef<ReconnectingWebSocket>()
46+
const ws = shallowRef<WebSocket>()
4747

4848
// Check if the current file is a configuration file
4949
function checkIfConfigFile(filename: string, content: string): boolean {
@@ -496,7 +496,8 @@ function useCodeCompletion() {
496496
return
497497
}
498498

499-
ws.value = llm.code_completion()
499+
const { ws: wsRef } = useWebSocket(llm.codeCompletionWebSocketUrl, false)
500+
ws.value = wsRef.value!
500501

501502
editorRef.value = editor
502503

app/src/components/GeoLiteDownload/GeoLiteDownload.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { Ref } from 'vue'
33
import { CheckCircleOutlined, DownloadOutlined, InfoCircleOutlined } from '@ant-design/icons-vue'
44
import geolite from '@/api/geolite'
55
import { formatDateTime } from '@/lib/helper'
6-
import websocket from '@/lib/websocket'
6+
import { useWebSocket } from '@/lib/websocket'
77
88
interface Emits {
99
(e: 'downloadComplete'): void
@@ -55,16 +55,17 @@ function downloadGeoLiteDB() {
5555
downloadProgress.value = 0
5656
downloadMessage.value = $gettext('Starting download...')
5757
58-
const ws = websocket('/api/geolite/download', false)
58+
const { ws } = useWebSocket('/api/geolite/download', false)
59+
const socket = ws.value!
5960
6061
let isFailed = false
6162
let currentPhase = 'download' // 'download' or 'decompress'
6263
63-
ws.onopen = () => {
64-
// WebSocket connected, server will start download
64+
socket.onopen = () => {
65+
socket.send('start')
6566
}
6667
67-
ws.onmessage = async m => {
68+
socket.onmessage = async m => {
6869
const r = JSON.parse(m.data)
6970
7071
// Update message and detect phase changes
@@ -99,13 +100,13 @@ function downloadGeoLiteDB() {
99100
}
100101
}
101102
102-
ws.onerror = () => {
103+
socket.onerror = () => {
103104
isFailed = true
104105
downloadStatus.value = 'exception'
105106
downloadMessage.value = $gettext('Download failed')
106107
}
107108
108-
ws.onclose = async () => {
109+
socket.onclose = async () => {
109110
if (isFailed) {
110111
downloading.value = false
111112
return

app/src/components/NamespaceTabs/NamespaceTabs.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const loading = ref({
5353
const currentNamespace = computed(() => {
5454
if (!modelValue.value || modelValue.value === 0)
5555
return null
56-
return namespaces.value.find(g => g.id === Number(modelValue.value))
56+
return namespaces.value.find(g => g.id === modelValue.value)
5757
})
5858
5959
// Get the list of nodes in the current group
@@ -74,7 +74,7 @@ async function handleReloadNginx() {
7474
if (!currentNamespace.value || !syncNodes.value.length)
7575
return
7676
77-
const nodeIds = syncNodes.value.map(node => node.id)
77+
const nodeIds = syncNodes.value.map(node => node.id).filter(id => id !== undefined)
7878
7979
loading.value.reload = true
8080
try {
@@ -94,7 +94,7 @@ async function handleRestartNginx() {
9494
if (!currentNamespace.value || !syncNodes.value.length)
9595
return
9696
97-
const nodeIds = syncNodes.value.map(node => node.id)
97+
const nodeIds = syncNodes.value.map(node => node.id).filter(id => id !== undefined)
9898
9999
loading.value.restart = true
100100
try {

0 commit comments

Comments
 (0)