远程遥控界面编写
9
assets/svgs/remote_alert.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor">
|
||||
<path d="M8.688 2a2 2 0 0 0-1.414.586L2.586 7.274A2 2 0 0 0 2 8.688v6.624a2 2 0 0 0 .586 1.414l4.688 4.688A2 2 0 0 0 8.688 22h6.624a2 2 0 0 0 1.414-.586l4.688-4.688A2 2 0 0 0 22 15.312V8.688a2 2 0 0 0-.586-1.414l-4.688-4.688A2 2 0 0 0 15.312 2H8.688z"/>
|
||||
<path d="M12 7.5c.552 0 1 .448 1 1v4a1 1 0 1 1-2 0v-4c0-.552.448-1 1-1z" fill="currentColor"/>
|
||||
<circle cx="12" cy="16.5" r="1" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 542 B |
1
assets/svgs/remote_back.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left-icon lucide-arrow-left"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>
|
||||
|
After Width: | Height: | Size: 289 B |
1
assets/svgs/remote_battery_charging.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-charging-icon lucide-battery-charging"><path d="m11 7-3 5h4l-3 5"/><path d="M14.856 6H16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.935"/><path d="M22 14v-4"/><path d="M5.14 18H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2.936"/></svg>
|
||||
|
After Width: | Height: | Size: 423 B |
1
assets/svgs/remote_battery_full.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-full-icon lucide-battery-full"><path d="M10 10v4"/><path d="M14 10v4"/><path d="M22 14v-4"/><path d="M6 10v4"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
1
assets/svgs/remote_battery_low.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-low-icon lucide-battery-low"><path d="M22 14v-4"/><path d="M6 14v-4"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>
|
||||
|
After Width: | Height: | Size: 335 B |
1
assets/svgs/remote_battery_middle.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-medium-icon lucide-battery-medium"><path d="M10 14v-4"/><path d="M22 14v-4"/><path d="M6 14v-4"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>
|
||||
|
After Width: | Height: | Size: 362 B |
1
assets/svgs/remote_battery_none.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-icon lucide-battery"><path d="M 22 14 L 22 10"/><rect x="2" y="6" width="16" height="12" rx="2"/></svg>
|
||||
|
After Width: | Height: | Size: 313 B |
1
assets/svgs/remote_battery_warning.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-battery-warning-icon lucide-battery-warning"><path d="M10 17h.01"/><path d="M10 7v6"/><path d="M14 6h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2"/><path d="M22 14v-4"/><path d="M6 18H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2"/></svg>
|
||||
|
After Width: | Height: | Size: 418 B |
1
assets/svgs/remote_down.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-from-line-icon lucide-arrow-down-from-line"><path d="M19 3H5"/><path d="M12 21V7"/><path d="m6 15 6 6 6-6"/></svg>
|
||||
|
After Width: | Height: | Size: 327 B |
1
assets/svgs/remote_expand.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon lucide-chevron-right"><path d="m9 18 6-6-6-6"/></svg>
|
||||
|
After Width: | Height: | Size: 274 B |
1
assets/svgs/remote_flame.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-flame-icon lucide-flame"><path d="M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4"/></svg>
|
||||
|
After Width: | Height: | Size: 335 B |
25
assets/svgs/remote_flame_minus.svg
Normal file
@@ -0,0 +1,25 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24">
|
||||
|
||||
<!-- 原来的主体图形 -->
|
||||
<path
|
||||
d="M12 3
|
||||
q1 4 4 6.5
|
||||
t3 5.5
|
||||
a1 1 0 0 1 -14 0
|
||||
a5 5 0 0 1 1 -3
|
||||
a1 1 0 0 0 5 0
|
||||
c0 -2 -1.5 -3 -1.5 -5
|
||||
q0 -2 2.5 -4"
|
||||
fill="black"/>
|
||||
|
||||
<!-- 右上角水平减号 -->
|
||||
<path
|
||||
d="M16 4 L20 4"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
fill="none"
|
||||
stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 511 B |
33
assets/svgs/remote_flame_plus.svg
Normal file
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24">
|
||||
|
||||
<!-- 原来的主体图形 -->
|
||||
<path
|
||||
d="M12 3
|
||||
q1 4 4 6.5
|
||||
t3 5.5
|
||||
a1 1 0 0 1 -14 0
|
||||
a5 5 0 0 1 1 -3
|
||||
a1 1 0 0 0 5 0
|
||||
c0 -2 -1.5 -3 -1.5 -5
|
||||
q0 -2 2.5 -4"
|
||||
fill="black"/>
|
||||
|
||||
<!-- 右上角加号:水平线 -->
|
||||
<path
|
||||
d="M16 4 L20 4"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
fill="none"
|
||||
stroke-linecap="round"/>
|
||||
|
||||
<!-- 右上角加号:垂直线 -->
|
||||
<path
|
||||
d="M18 2 L18 6"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
fill="none"
|
||||
stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 694 B |
1
assets/svgs/remote_fresh.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw-icon lucide-refresh-cw"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg>
|
||||
|
After Width: | Height: | Size: 411 B |
1
assets/svgs/remote_is_controlling.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-activity-icon lucide-activity"><path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/></svg>
|
||||
|
After Width: | Height: | Size: 373 B |
1
assets/svgs/remote_layers.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layers-icon lucide-layers"><path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"/><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"/><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"/></svg>
|
||||
|
After Width: | Height: | Size: 525 B |
1
assets/svgs/remote_lock.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock-icon lucide-lock"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
1
assets/svgs/remote_lock_open.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lock-open-icon lucide-lock-open"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 9.9-1"/></svg>
|
||||
|
After Width: | Height: | Size: 333 B |
1
assets/svgs/remote_minus.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus-icon lucide-minus"><path d="M5 12h14"/></svg>
|
||||
|
After Width: | Height: | Size: 253 B |
1
assets/svgs/remote_net.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-up-icon lucide-arrow-down-up"><path d="m3 16 4 4 4-4"/><path d="M7 20V4"/><path d="m21 8-4-4-4 4"/><path d="M17 4v16"/></svg>
|
||||
|
After Width: | Height: | Size: 338 B |
1
assets/svgs/remote_plus.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
|
||||
|
After Width: | Height: | Size: 271 B |
1
assets/svgs/remote_power.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-power-icon lucide-power"><path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.77.04"/></svg>
|
||||
|
After Width: | Height: | Size: 293 B |
1
assets/svgs/remote_scissors.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scissors-icon lucide-scissors"><circle cx="6" cy="6" r="3"/><path d="M8.12 8.12 12 12"/><path d="M20 4 8.12 15.88"/><circle cx="6" cy="18" r="3"/><path d="M14.8 14.8 20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 382 B |
1
assets/svgs/remote_unexpand.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-left-icon lucide-chevron-left"><path d="m15 18-6-6 6-6"/></svg>
|
||||
|
After Width: | Height: | Size: 273 B |
1
assets/svgs/remote_up.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-from-line-icon lucide-arrow-up-from-line"><path d="m18 9-6-6-6 6"/><path d="M12 3v14"/><path d="M5 21h14"/></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
36
assets/svgs/remote_video_left.svg
Normal file
@@ -0,0 +1,36 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<!-- 右侧“播放/视频”形状 -->
|
||||
<path
|
||||
d="M16 15
|
||||
L21.223 18.482
|
||||
a0.5 0.5 0 0 0 0.777 -0.416
|
||||
V9.87
|
||||
a0.5 0.5 0 0 0 -0.752 -0.432
|
||||
L16 12.5"/>
|
||||
|
||||
<!-- 左侧矩形主体 -->
|
||||
<path
|
||||
d="M4 8
|
||||
L14 8
|
||||
A2 2 0 0 1 16 10
|
||||
L16 18
|
||||
A2 2 0 0 1 14 20
|
||||
L4 20
|
||||
A2 2 0 0 1 2 18
|
||||
L2 10
|
||||
A2 2 0 0 1 4 8
|
||||
Z"/>
|
||||
|
||||
<!-- 左上角“外接/上传”折角 -->
|
||||
<path
|
||||
d="M17 1 L17 7 L21 7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 721 B |
38
assets/svgs/remote_video_left_off.svg
Normal file
@@ -0,0 +1,38 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<!-- 右侧视频/播放形状 -->
|
||||
<path
|
||||
d="M16 15
|
||||
L21.223 18.482
|
||||
a0.5 0.5 0 0 0 0.777 -0.416
|
||||
V9.87
|
||||
a0.5 0.5 0 0 0 -0.752 -0.432
|
||||
L16 12.5"/>
|
||||
|
||||
<!-- 左侧矩形主体 -->
|
||||
<path
|
||||
d="M4 8
|
||||
L14 8
|
||||
A2 2 0 0 1 16 10
|
||||
L16 18
|
||||
A2 2 0 0 1 14 20
|
||||
L4 20
|
||||
A2 2 0 0 1 2 18
|
||||
L2 10
|
||||
A2 2 0 0 1 4 8
|
||||
Z"/>
|
||||
|
||||
<!-- 左上角折角 -->
|
||||
<path d="M17 1 L17 7 L21 7"/>
|
||||
|
||||
<!-- 斜杠禁用线 -->
|
||||
<path d="M22 3 L2 22"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 746 B |
40
assets/svgs/remote_video_right.svg
Normal file
@@ -0,0 +1,40 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<!-- 右侧视频/播放形状 -->
|
||||
<path
|
||||
d="m16 15
|
||||
l5.223 3.482
|
||||
a0.5 0.5 0 0 0 0.777 -0.416
|
||||
V9.87
|
||||
a0.5 0.5 0 0 0 -0.752 -0.432
|
||||
L16 12.5"/>
|
||||
|
||||
<!-- 左侧矩形主体 -->
|
||||
<path
|
||||
d="M4 8
|
||||
L14 8
|
||||
A2 2 0 0 1 16 10
|
||||
L16 18
|
||||
A2 2 0 0 1 14 20
|
||||
L4 20
|
||||
A2 2 0 0 1 2 18
|
||||
L2 10
|
||||
A2 2 0 0 1 4 8
|
||||
Z"/>
|
||||
|
||||
<!-- 右上角“广播/音量”形状 -->
|
||||
<path
|
||||
d="M17 1 L17 8
|
||||
M17 1
|
||||
C22 0.5 22 6 17 6
|
||||
M17 6
|
||||
L22 8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 771 B |
43
assets/svgs/remote_video_right_off.svg
Normal file
@@ -0,0 +1,43 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<!-- 右侧视频/扬声器形状 -->
|
||||
<path
|
||||
d="m16 15
|
||||
l5.223 3.482
|
||||
a0.5 0.5 0 0 0 0.777 -0.416
|
||||
V9.87
|
||||
a0.5 0.5 0 0 0 -0.752 -0.432
|
||||
L16 12.5"/>
|
||||
|
||||
<!-- 左侧矩形主体 -->
|
||||
<path
|
||||
d="M4 8
|
||||
L14 8
|
||||
A2 2 0 0 1 16 10
|
||||
L16 18
|
||||
A2 2 0 0 1 14 20
|
||||
L4 20
|
||||
A2 2 0 0 1 2 18
|
||||
L2 10
|
||||
A2 2 0 0 1 4 8
|
||||
Z"/>
|
||||
|
||||
<!-- 右上角广播/音量曲线 -->
|
||||
<path
|
||||
d="M17 1 L17 8
|
||||
M17 1
|
||||
C22 0.5 22 6 17 6
|
||||
M17 6
|
||||
L22 8"/>
|
||||
|
||||
<!-- 禁用斜线 -->
|
||||
<path d="M22 3 L2 22"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 823 B |
7
assets/svgs/remote_zap.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor">
|
||||
<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 299 B |
1
assets/www/webrtc/jswebrtc.min.js
vendored
Normal file
@@ -1,117 +0,0 @@
|
||||
class WebSocketClient {
|
||||
constructor(url) {
|
||||
this.url = url;
|
||||
this.socket = null;
|
||||
this.connected = false;
|
||||
this.reconnecting = false;
|
||||
this.reconnectInterval = 3000; // 重连间隔(ms)
|
||||
this.maxReconnectAttempts = 10; // 最大重连次数
|
||||
this.reconnectAttempts = 0;
|
||||
this.messageQueue = []; // 消息队列
|
||||
|
||||
// 事件回调
|
||||
this.onConnect = null;
|
||||
this.onMessage = null;
|
||||
this.onClose = null;
|
||||
this.onError = null;
|
||||
}
|
||||
|
||||
// 连接WebSocket服务器
|
||||
connect() {
|
||||
if (this.socket && (this.socket.readyState === WebSocket.CONNECTING || this.socket.readyState === WebSocket.OPEN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.socket = new WebSocket(this.url);
|
||||
|
||||
this.socket.onopen = (event) => {
|
||||
this.connected = true;
|
||||
this.reconnecting = false;
|
||||
this.reconnectAttempts = 0;
|
||||
console.log('WebSocket连接已建立');
|
||||
|
||||
// 发送队列中的所有消息
|
||||
this._sendQueuedMessages();
|
||||
|
||||
if (typeof this.onConnect === 'function') {
|
||||
this.onConnect(event);
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
console.log('收到消息:', event.data);
|
||||
this.onMessage(event.data);
|
||||
};
|
||||
|
||||
this.socket.onclose = (event) => {
|
||||
this.connected = false;
|
||||
console.log('WebSocket连接已关闭,代码:', event.code, '原因:', event.reason);
|
||||
|
||||
if (typeof this.onClose === 'function') {
|
||||
this.onClose(event);
|
||||
}
|
||||
|
||||
// 非主动关闭时尝试重连
|
||||
if (!this.reconnecting && event.code !== 1000) {
|
||||
this._scheduleReconnect();
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.onerror = (error) => {
|
||||
console.error('WebSocket错误:', error);
|
||||
if (typeof this.onError === 'function') {
|
||||
this.onError(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
send(message) {
|
||||
if (this.connected && this.socket.readyState === WebSocket.OPEN) {
|
||||
this.socket.send(message);
|
||||
} else {
|
||||
// 连接未建立,将消息加入队列
|
||||
this.messageQueue.push(message);
|
||||
if (!this.reconnecting) {
|
||||
this._scheduleReconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭连接
|
||||
close(code = 1000, reason = '') {
|
||||
this.reconnecting = false;
|
||||
if (this.socket) {
|
||||
this.socket.close(code, reason);
|
||||
}
|
||||
}
|
||||
|
||||
// 安排重连
|
||||
_scheduleReconnect() {
|
||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
this.reconnecting = true;
|
||||
this.reconnectAttempts++;
|
||||
const delay = this.reconnectInterval * Math.min(1, this.reconnectAttempts / 3); // 指数退避
|
||||
|
||||
console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts}),${delay/1000}秒后...`);
|
||||
setTimeout(() => {
|
||||
console.log('正在重连...');
|
||||
this.connect();
|
||||
}, delay);
|
||||
} else {
|
||||
console.error('达到最大重连次数,停止重连');
|
||||
this.reconnecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 发送队列中的消息
|
||||
_sendQueuedMessages() {
|
||||
if (this.messageQueue.length > 0) {
|
||||
console.log(`发送队列中的${this.messageQueue.length}条消息`);
|
||||
this.messageQueue.forEach(message => {
|
||||
this.socket.send(message);
|
||||
});
|
||||
this.messageQueue = [];
|
||||
}
|
||||
}
|
||||
}
|
||||