A:增加Gzip压缩
This commit is contained in:
1 parent
7d1d3d9220
commit
e4c60ccf8d
6 files changed
+100
-48
No files matched your search
@@ -1,5 +1,7 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Common.Logger;
|
using Common.Logger;
|
||||||
@@ -114,6 +116,36 @@ public class WebSocketManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩需要发送的数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="json"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static byte[] Compress(string json)
|
||||||
|
{
|
||||||
|
byte[] inputBytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
using var outputStream = new MemoryStream();
|
||||||
|
// leaveOpen: false,确保 DeflateStream 完全关闭时写入尾部
|
||||||
|
using (var deflate = new DeflateStream(outputStream, CompressionLevel.Fastest))
|
||||||
|
{
|
||||||
|
deflate.Write(inputBytes, 0, inputBytes.Length);
|
||||||
|
} // Dispose 在这里调用,确保数据写入完成
|
||||||
|
|
||||||
|
return outputStream.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] CompressGzip(string json)
|
||||||
|
{
|
||||||
|
byte[] inputBytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
using var outputStream = new MemoryStream();
|
||||||
|
using (var gzip = new GZipStream(outputStream, CompressionLevel.Fastest))
|
||||||
|
{
|
||||||
|
gzip.Write(inputBytes, 0, inputBytes.Length);
|
||||||
|
}
|
||||||
|
return outputStream.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 停止服务器
|
// 停止服务器
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
@@ -159,7 +191,7 @@ public class WebSocketManager
|
|||||||
if (_connections.TryGetValue(socketId, out var connection))
|
if (_connections.TryGetValue(socketId, out var connection))
|
||||||
{
|
{
|
||||||
connection.Socket.Close();
|
connection.Socket.Close();
|
||||||
|
|
||||||
// OnConnectionClose会被自动调用,但我们可以在这里预先记录关闭原因
|
// OnConnectionClose会被自动调用,但我们可以在这里预先记录关闭原因
|
||||||
Log.Information($"主动关闭连接: {socketId}, 原因: {reason}");
|
Log.Information($"主动关闭连接: {socketId}, 原因: {reason}");
|
||||||
}
|
}
|
||||||
@@ -247,7 +279,7 @@ public class WebSocketManager
|
|||||||
{
|
{
|
||||||
_connections.TryRemove(socket.ConnectionInfo.Id, out var conn);
|
_connections.TryRemove(socket.ConnectionInfo.Id, out var conn);
|
||||||
string? uuid = null;
|
string? uuid = null;
|
||||||
|
|
||||||
if (conn?.Uuid != null)
|
if (conn?.Uuid != null)
|
||||||
{
|
{
|
||||||
uuid = conn.Uuid;
|
uuid = conn.Uuid;
|
||||||
@@ -328,7 +360,7 @@ public class WebSocketManager
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var json = JsonHelper.ToJson(message);
|
var json = JsonHelper.ToJson(message);
|
||||||
await socket.Socket.Send(json);
|
await socket.Socket.Send(CompressGzip(json));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -370,7 +402,7 @@ public class WebSocketManager
|
|||||||
|
|
||||||
foreach (var connection in _connections.Values)
|
foreach (var connection in _connections.Values)
|
||||||
{
|
{
|
||||||
tasks.Add(connection.Socket.Send(json));
|
tasks.Add(connection.Socket.Send(CompressGzip(json)));
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -405,11 +437,12 @@ public class WebSocketManager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ClientConnection? GetConnection(string uuid)
|
public ClientConnection? GetConnection(string uuid)
|
||||||
{
|
{
|
||||||
if (_uuidToSocketId.TryGetValue(uuid, out var socketId) &&
|
if (_uuidToSocketId.TryGetValue(uuid, out var socketId) &&
|
||||||
_connections.TryGetValue(socketId, out var connection))
|
_connections.TryGetValue(socketId, out var connection))
|
||||||
{
|
{
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,14 +524,14 @@ public static class WebSocketManagerUsageExample
|
|||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
var wsManager = WebSocketManager.Instance;
|
var wsManager = WebSocketManager.Instance;
|
||||||
|
|
||||||
// 订阅连接关闭事件
|
// 订阅连接关闭事件
|
||||||
wsManager.SubscribeConnectionClosed(OnConnectionClosed);
|
wsManager.SubscribeConnectionClosed(OnConnectionClosed);
|
||||||
|
|
||||||
// 启动服务器
|
// 启动服务器
|
||||||
wsManager.Start();
|
wsManager.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnConnectionClosed(ConnectionClosedEventArgs args)
|
private static void OnConnectionClosed(ConnectionClosedEventArgs args)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"连接已关闭:");
|
Console.WriteLine($"连接已关闭:");
|
||||||
@@ -506,20 +539,20 @@ public static class WebSocketManagerUsageExample
|
|||||||
Console.WriteLine($" UUID: {args.Uuid ?? "未知"}");
|
Console.WriteLine($" UUID: {args.Uuid ?? "未知"}");
|
||||||
Console.WriteLine($" 关闭时间: {args.ClosedAt}");
|
Console.WriteLine($" 关闭时间: {args.ClosedAt}");
|
||||||
Console.WriteLine($" 关闭原因: {args.Reason ?? "未知"}");
|
Console.WriteLine($" 关闭原因: {args.Reason ?? "未知"}");
|
||||||
|
|
||||||
// 在这里可以执行清理逻辑,比如:
|
// 在这里可以执行清理逻辑,比如:
|
||||||
// - 清理用户相关的缓存数据
|
// - 清理用户相关的缓存数据
|
||||||
// - 更新用户在线状态
|
// - 更新用户在线状态
|
||||||
// - 记录用户离线时间
|
// - 记录用户离线时间
|
||||||
// - 通知其他相关服务
|
// - 通知其他相关服务
|
||||||
|
|
||||||
// 示例:清理用户数据
|
// 示例:清理用户数据
|
||||||
if (!string.IsNullOrEmpty(args.Uuid))
|
if (!string.IsNullOrEmpty(args.Uuid))
|
||||||
{
|
{
|
||||||
CleanupUserData(args.Uuid);
|
CleanupUserData(args.Uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CleanupUserData(string uuid)
|
private static void CleanupUserData(string uuid)
|
||||||
{
|
{
|
||||||
// 实现用户数据清理逻辑
|
// 实现用户数据清理逻辑
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"@vicons/ionicons5": "^0.13.0",
|
"@vicons/ionicons5": "^0.13.0",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"unplugin-auto-import": "^19.3.0",
|
"unplugin-auto-import": "^19.3.0",
|
||||||
"unplugin-vue-components": "^28.7.0",
|
"unplugin-vue-components": "^28.7.0",
|
||||||
|
|||||||
Generated
+8
@@ -17,6 +17,9 @@ importers:
|
|||||||
gsap:
|
gsap:
|
||||||
specifier: ^3.13.0
|
specifier: ^3.13.0
|
||||||
version: 3.13.0
|
version: 3.13.0
|
||||||
|
pako:
|
||||||
|
specifier: ^2.1.0
|
||||||
|
version: 2.1.0
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.2(typescript@5.8.3)(vue@3.5.14(typescript@5.8.3))
|
version: 3.0.2(typescript@5.8.3)(vue@3.5.14(typescript@5.8.3))
|
||||||
@@ -1800,6 +1803,9 @@ packages:
|
|||||||
package-json-from-dist@1.0.1:
|
package-json-from-dist@1.0.1:
|
||||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, tarball: https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz}
|
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, tarball: https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz}
|
||||||
|
|
||||||
|
pako@2.1.0:
|
||||||
|
resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
|
||||||
|
|
||||||
parent-module@1.0.1:
|
parent-module@1.0.1:
|
||||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, tarball: https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz}
|
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, tarball: https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -4133,6 +4139,8 @@ snapshots:
|
|||||||
|
|
||||||
package-json-from-dist@1.0.1: {}
|
package-json-from-dist@1.0.1: {}
|
||||||
|
|
||||||
|
pako@2.1.0: {}
|
||||||
|
|
||||||
parent-module@1.0.1:
|
parent-module@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
callsites: 3.1.0
|
callsites: 3.1.0
|
||||||
|
|||||||
@@ -146,42 +146,44 @@ const getLayout = (route) => {
|
|||||||
:theme-overrides="themeStore.themeOverrides"
|
:theme-overrides="themeStore.themeOverrides"
|
||||||
:theme="themeStore.theme"
|
:theme="themeStore.theme"
|
||||||
>
|
>
|
||||||
<n-global-style />
|
<n-message-provider>
|
||||||
|
<n-global-style />
|
||||||
|
|
||||||
<!-- 可拖动的导航栏 -->
|
<!-- 可拖动的导航栏 -->
|
||||||
<div
|
<div
|
||||||
v-if="isShowGenerateRouter"
|
v-if="isShowGenerateRouter"
|
||||||
ref="navRef"
|
ref="navRef"
|
||||||
class="nav-container"
|
class="nav-container"
|
||||||
:style="{ left: `${navPosition.x}px`, top: `${navPosition.y}px` }"
|
:style="{ left: `${navPosition.x}px`, top: `${navPosition.y}px` }"
|
||||||
@mousedown="startDrag"
|
@mousedown="startDrag"
|
||||||
>
|
>
|
||||||
<div class="drag-handle">
|
<div class="drag-handle">
|
||||||
<span class="drag-icon">≡</span>
|
<span class="drag-icon">≡</span>
|
||||||
|
</div>
|
||||||
|
<ul class="route-list">
|
||||||
|
<li v-for="(subRoute, index) in subRouteLists" :key="index" class="route-item">
|
||||||
|
<n-button
|
||||||
|
:type="isActive(subRoute.path) ? 'primary' : 'default'"
|
||||||
|
@click="listClickJump(subRoute)"
|
||||||
|
>
|
||||||
|
{{ subRoute.displayName }}
|
||||||
|
</n-button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<ul class="route-list">
|
|
||||||
<li v-for="(subRoute, index) in subRouteLists" :key="index" class="route-item">
|
|
||||||
<n-button
|
|
||||||
:type="isActive(subRoute.path) ? 'primary' : 'default'"
|
|
||||||
@click="listClickJump(subRoute)"
|
|
||||||
>
|
|
||||||
{{ subRoute.displayName }}
|
|
||||||
</n-button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 展示主要内容 -->
|
<!-- 展示主要内容 -->
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<router-view v-slot="{ Component, route }">
|
<router-view v-slot="{ Component, route }">
|
||||||
<transition name="fade-slide" mode="out-in">
|
<transition name="fade-slide" mode="out-in">
|
||||||
<component :is="getLayout(route)">
|
<component :is="getLayout(route)">
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
</component>
|
</component>
|
||||||
</transition>
|
</transition>
|
||||||
</router-view>
|
</router-view>
|
||||||
<!-- <network-connection-panel2/>-->
|
<!-- <network-connection-panel2/>-->
|
||||||
</div>
|
</div>
|
||||||
|
</n-message-provider>
|
||||||
</n-config-provider>
|
</n-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import CSharpBridgeV2 from '@/correspond/CSharpBridgeV2'
|
|||||||
import { ref, Ref } from 'vue'
|
import { ref, Ref } from 'vue'
|
||||||
import { logB } from '@/utils/logHelper/logUtils'
|
import { logB } from '@/utils/logHelper/logUtils'
|
||||||
import { useUuidStore } from '@/stores/uuidStore'
|
import { useUuidStore } from '@/stores/uuidStore'
|
||||||
|
import pako from "pako";
|
||||||
|
|
||||||
export class WebSocketManager {
|
export class WebSocketManager {
|
||||||
private socket: WebSocket | null = null
|
private socket: WebSocket | null = null
|
||||||
@@ -102,10 +103,17 @@ export class WebSocketManager {
|
|||||||
this.startHeartbeat()
|
this.startHeartbeat()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.socket.onmessage = (event) => {
|
this.socket.onmessage = async (event) => {
|
||||||
try {
|
try {
|
||||||
const message: WebSocketResponse = JSON.parse(event.data)
|
const arrayBuffer: ArrayBuffer = event.data instanceof Blob
|
||||||
this.handleMessage(message)
|
? await event.data.arrayBuffer()
|
||||||
|
: event.data;
|
||||||
|
|
||||||
|
const uint8Array = new Uint8Array(arrayBuffer);
|
||||||
|
const decompressed = pako.inflate(uint8Array, { to: "string" });
|
||||||
|
|
||||||
|
const json = JSON.parse(decompressed);
|
||||||
|
this.handleMessage(json)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error parsing WebSocket message:', error)
|
console.error('Error parsing WebSocket message:', error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ onMounted(() => {
|
|||||||
// 发送请求【请求订阅软件列表】
|
// 发送请求【请求订阅软件列表】
|
||||||
const subAppInfo: SubscriptionProcessInfo = {
|
const subAppInfo: SubscriptionProcessInfo = {
|
||||||
subscriptionType: 'ProcessInfo',
|
subscriptionType: 'ProcessInfo',
|
||||||
interval: 1000,
|
interval: 400,
|
||||||
processIds: newValue1.processIds,
|
processIds: newValue1.processIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user