优化性能结构/延迟加载

新增测试代码用于测试性能
This commit is contained in:
YHH
2025-07-02 00:13:29 +08:00
parent 6bd9c1055c
commit bb19f752a1
23 changed files with 3425 additions and 512 deletions

View File

@@ -0,0 +1,448 @@
import { EntitySystem, Entity, Matcher, Time } from '@esengine/ecs-framework';
import { NetworkComponent } from '../components';
/**
* 网络系统 - 处理网络同步和连接管理
*/
export class NetworkSystem extends EntitySystem {
/** 网络统计 */
private networkStats = {
totalEntities: 0,
connectedEntities: 0,
totalMessagesSent: 0,
totalMessagesReceived: 0,
averagePing: 0,
networkTraffic: 0
};
/** 消息处理队列 */
private globalMessageQueue: Array<{
from: string;
to: string;
messageType: string;
data: any;
timestamp: number;
priority: number;
}> = [];
constructor() {
// 处理具有网络组件的实体
super(Matcher.empty().all(NetworkComponent));
}
/**
* 处理所有实体
*/
protected process(entities: Entity[]): void {
const deltaTime = Time.deltaTime;
this.networkStats.totalEntities = entities.length;
this.networkStats.connectedEntities = entities.filter(e =>
e.getComponent(NetworkComponent)?.connectionState === 'connected'
).length;
for (const entity of entities) {
this.processEntity(entity, deltaTime);
}
// 处理全局消息队列
this.processGlobalMessages();
// 更新网络统计
this.updateGlobalNetworkStats(entities);
}
/**
* 处理单个实体
*/
private processEntity(entity: Entity, deltaTime: number): void {
const network = entity.getComponent(NetworkComponent);
if (!network) return;
// 更新网络统计
network.updateNetworkStats(deltaTime);
// 处理连接状态
this.updateConnectionState(network, deltaTime);
// 处理消息队列
this.processEntityMessages(network, entity);
// 处理数据同步
this.processSynchronization(network, deltaTime);
// 处理群组通信
this.processGroupCommunication(network);
}
/**
* 更新连接状态
*/
private updateConnectionState(network: NetworkComponent, deltaTime: number): void {
const currentTime = Date.now();
switch (network.connectionState) {
case 'disconnected':
// 尝试连接
if (network.config.autoReconnect &&
network.networkStats.reconnectCount < network.config.maxReconnectAttempts) {
network.connectionState = 'connecting';
network.connection.lastHeartbeat = currentTime;
}
break;
case 'connecting':
// 模拟连接过程
if (Math.random() > 0.1) { // 90% 成功率
network.connectionState = 'connected';
network.connection.sessionId = this.generateSessionId();
network.connection.serverId = 'server_001';
network.connection.lastHeartbeat = currentTime;
} else if (currentTime - network.connection.lastHeartbeat > 5000) {
// 连接超时
network.connectionState = 'error';
network.networkStats.errorCount++;
}
break;
case 'connected':
// 维持连接心跳
if (currentTime - network.connection.lastHeartbeat > network.config.heartbeatInterval) {
this.sendHeartbeat(network);
network.connection.lastHeartbeat = currentTime;
}
// 模拟网络质量变化
network.connection.ping = Math.random() * 100 + 20; // 20-120ms
network.connection.packetLoss = Math.random() * 0.05; // 0-5%
network.connection.bandwidth = 1000 + Math.random() * 500; // 1000-1500 Kbps
break;
case 'error':
// 错误状态,尝试重连
if (network.config.autoReconnect &&
network.networkStats.reconnectCount < network.config.maxReconnectAttempts) {
network.connectionState = 'disconnected';
network.networkStats.reconnectCount++;
}
break;
}
}
/**
* 处理实体消息
*/
private processEntityMessages(network: NetworkComponent, entity: Entity): void {
// 处理传出消息
const outgoingMessages = network.messageQueue.outgoing.slice();
network.messageQueue.outgoing = [];
for (const message of outgoingMessages) {
if (this.sendMessage(network, message)) {
this.networkStats.totalMessagesSent++;
network.networkStats.totalBytesSent += this.estimateMessageSize(message);
} else {
// 发送失败,重新加入队列
message.attempts++;
if (message.attempts < message.maxAttempts) {
network.messageQueue.outgoing.push(message);
}
}
}
// 处理传入消息
this.processIncomingMessages(network, entity);
}
/**
* 发送消息
*/
private sendMessage(network: NetworkComponent, message: any): boolean {
if (network.connectionState !== 'connected') {
return false;
}
// 模拟网络延迟和丢包
const shouldDelay = Math.random() < 0.3; // 30% 概率有延迟
const shouldDrop = Math.random() < network.connection.packetLoss;
if (shouldDrop) {
network.networkStats.errorCount++;
return false;
}
// 添加到全局消息队列
this.globalMessageQueue.push({
from: network.networkId,
to: message.targetId,
messageType: message.messageType,
data: message.data,
timestamp: Date.now() + (shouldDelay ? Math.random() * 200 : 0),
priority: message.priority
});
return true;
}
/**
* 处理传入消息
*/
private processIncomingMessages(network: NetworkComponent, entity: Entity): void {
// 从全局队列中获取发给此实体的消息
const incomingMessages = this.globalMessageQueue.filter(msg =>
msg.to === network.networkId && msg.timestamp <= Date.now()
);
// 从全局队列中移除这些消息
this.globalMessageQueue = this.globalMessageQueue.filter(msg =>
!(msg.to === network.networkId && msg.timestamp <= Date.now())
);
// 处理消息
for (const message of incomingMessages) {
network.messageQueue.incoming.push({
senderId: message.from,
messageType: message.messageType,
data: message.data,
timestamp: message.timestamp,
processed: false
});
this.networkStats.totalMessagesReceived++;
network.networkStats.totalBytesReceived += this.estimateMessageSize(message);
// 立即处理某些类型的消息
this.handleSpecialMessages(network, message);
}
}
/**
* 处理特殊消息类型
*/
private handleSpecialMessages(network: NetworkComponent, message: any): void {
switch (message.messageType) {
case 'player_join_group':
// 处理加入群组消息
const groupData = message.data;
if (groupData.members && Array.isArray(groupData.members)) {
// 查找对应的网络组件并建立连接
groupData.members.forEach((memberId: string) => {
// 直接使用成员ID建立连接
network.connectToPlayer(memberId);
});
}
break;
case 'heartbeat':
// 心跳响应
network.connection.ping = Date.now() - message.data.timestamp;
break;
case 'sync_request':
// 同步请求
this.handleSyncRequest(network, message);
break;
}
}
/**
* 处理数据同步
*/
private processSynchronization(network: NetworkComponent, deltaTime: number): void {
const currentTime = Date.now();
const syncInterval = 1000 / network.config.syncFrequency; // 转换为毫秒
if (currentTime - network.syncData.lastSyncTime >= syncInterval) {
this.performSynchronization(network);
network.syncData.lastSyncTime = currentTime;
}
// 处理排队的更新
this.processQueuedUpdates(network);
}
/**
* 执行同步
*/
private performSynchronization(network: NetworkComponent): void {
if (network.syncData.dirtyFlags.size === 0) {
return; // 没有需要同步的数据
}
const syncData = {
networkId: network.networkId,
timestamp: Date.now(),
properties: Array.from(network.syncData.dirtyFlags),
checksum: this.calculateChecksum(network)
};
// 发送同步数据给连接的玩家
network.connectedPlayerIds.forEach(playerId => {
network.sendMessage(playerId, 'sync_data', syncData, 7);
});
// 记录同步历史
network.syncData.syncHistory.push({
timestamp: syncData.timestamp,
dataSize: this.estimateMessageSize(syncData),
properties: syncData.properties,
success: true
});
// 清理脏标记
network.syncData.dirtyFlags.clear();
}
/**
* 处理排队的更新
*/
private processQueuedUpdates(network: NetworkComponent): void {
// 按优先级和时间戳排序
network.syncData.queuedUpdates.sort((a, b) => {
if (a.priority !== b.priority) {
return b.priority - a.priority; // 高优先级优先
}
return a.timestamp - b.timestamp; // 时间戳早的优先
});
// 处理前10个更新
const updatesToProcess = network.syncData.queuedUpdates.splice(0, 10);
for (const update of updatesToProcess) {
network.markDirty(update.property);
}
}
/**
* 处理群组通信
*/
private processGroupCommunication(network: NetworkComponent): void {
if (network.groupMemberIds.length === 0) {
return;
}
// 群组消息广播
if (Math.random() < 0.01) { // 1% 概率发送群组消息
const groupMessage = {
type: 'group_update',
data: {
sender: network.networkId,
timestamp: Date.now(),
groupSize: network.groupMemberIds.length,
status: network.connectionState
}
};
network.groupMemberIds.forEach(memberId => {
if (memberId !== network.networkId) {
network.sendMessage(memberId, 'group_message', groupMessage, 5);
}
});
}
}
/**
* 处理全局消息
*/
private processGlobalMessages(): void {
// 移除过期消息
const currentTime = Date.now();
this.globalMessageQueue = this.globalMessageQueue.filter(msg =>
currentTime - msg.timestamp < 30000 // 30秒过期
);
// 按优先级排序
this.globalMessageQueue.sort((a, b) => b.priority - a.priority);
}
/**
* 更新全局网络统计
*/
private updateGlobalNetworkStats(entities: Entity[]): void {
let totalPing = 0;
let connectedCount = 0;
let totalTraffic = 0;
for (const entity of entities) {
const network = entity.getComponent(NetworkComponent);
if (network && network.connectionState === 'connected') {
totalPing += network.connection.ping;
connectedCount++;
totalTraffic += network.networkStats.totalBytesSent + network.networkStats.totalBytesReceived;
}
}
this.networkStats.averagePing = connectedCount > 0 ? totalPing / connectedCount : 0;
this.networkStats.networkTraffic = totalTraffic;
}
/**
* 辅助方法
*/
private generateSessionId(): string {
return 'session_' + Math.random().toString(36).substring(2, 15);
}
private estimateMessageSize(message: any): number {
return JSON.stringify(message).length;
}
private calculateChecksum(network: NetworkComponent): string {
// 简单的校验和计算
const data = JSON.stringify({
networkId: network.networkId,
connectionState: network.connectionState
});
return btoa(data).substring(0, 8);
}
private sendHeartbeat(network: NetworkComponent): void {
network.sendMessage('server', 'heartbeat', { timestamp: Date.now() }, 10);
}
private findNetworkComponentById(networkId: string): NetworkComponent | null {
// 这里应该有一个全局的网络组件注册表
// 为了简化我们返回null
return null;
}
private handleSyncRequest(network: NetworkComponent, message: any): void {
// 处理同步请求
const response = {
requestId: message.data.requestId,
data: this.gatherSyncData(network),
timestamp: Date.now()
};
network.sendMessage(message.from, 'sync_response', response, 8);
}
private gatherSyncData(network: NetworkComponent): any {
return {
networkId: network.networkId,
connectionState: network.connectionState,
ping: network.connection.ping,
groupSize: network.groupMemberIds.length
};
}
/**
* 系统初始化时调用
*/
public initialize(): void {
super.initialize();
console.log('🌐 网络系统已启动');
}
/**
* 获取系统统计信息
*/
public getSystemStats(): any {
return {
...this.networkStats,
globalMessageQueueSize: this.globalMessageQueue.length,
systemName: 'NetworkSystem'
};
}
}