FMS项目错误之Error #2044

本文记录了一次在使用FMS进行项目开发时遇到的连接错误事件处理问题,通过添加事件监听和处理函数成功解决了Error#2044和Error#2095的问题。详细分析了错误原因并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做一个基于FMS的项目。在通过客户端连接FMS服务器时,虽然已经连接成功,但是在flash的输出窗口还是有个一错误。如下:

Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetConnection was unable to invoke callback onBWDone. error=ReferenceError: Error #1069: Property onBWDone not found on connFMS and there is no default value.

百度谷歌了许多,但是都没有找到答案。于是仔细分析了错误提示。意思是没有处理AsyncErrorEvent类型的错误事件。于是给nc(NetConnection类型变量)添加了事件侦听器,侦听AsyncErrorEvent类型的错误事件。并添加处理函数。最后没有错误了。至于为什么要这样做我还没有弄明白,在此先记录下来,便于日后查阅。以后研究深入了,再做详解。


英文好的朋友可以看看这篇文章,感觉外国人写东西都挺详细的。

http://www.adobe.com/devnet/flash/quickstart/metadata_cue_points.html

修改问题:PS C:\Users\Administrator\Desktop\project> .\verify_event_center.ps1 === 事件中心验证 === ✅ 核心模块导入成功 SUCCESS �����¼�����: 15 测试输出: === 验证完成 ===其它问题:::警告: 此模块应作为库导入,而非直接运行 === EventCenter标准化测试 === Traceback (most recent call last): File "C:\Users\Administrator\Desktop\project\core\event_center.py", line 300, in <module> event_center.subscribe(EventType.TEST_EVENT, test_handler) File "C:\Users\Administrator\Desktop\project\core\event_center.py", line 139, in subscribe raise TypeError("event_type 必须是字符串或EventType枚举") TypeError: event_type 必须是字符串或EventType枚举 进程已结束,退出代码为 1代码#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 事件中心模块 (最终优化版) """ import os import sys from pathlib import Path # 关键修复1:更可靠的路径处理 def _init_paths(): """更健壮的路径初始化""" try: # 直接定位项目根目录(假设core是子目录) current_dir = Path(__file__).parent root_dir = current_dir.parent if current_dir.name == "core" else current_dir # 标准化路径处理 if str(root_dir) not in sys.path: sys.path.insert(0, str(root_dir)) # 调试信息 if __debug__: print(f"[DEBUG] 最终项目根目录: {root_dir}") print(f"[DEBUG] 有效Python路径:") for p in sys.path: if "project" in p or "python" in p: print(f" - {p}") except Exception as e: print(f"[CRITICAL] 路径初始化失败: {e}") raise import logging import threading import uuid import time from enum import Enum, auto from typing import Dict, List, Callable, Optional, Any, Set, Tuple, DefaultDict, Union from collections import defaultdict from dataclasses import dataclass, field from concurrent.futures import ThreadPoolExecutor logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # 解决导入问题的关键修改:确保模块作为独立实体导入 if __name__ == "__main__": print("警告: 此模块应作为库导入,而非直接运行") from enum import Enum, auto class EventType(Enum): """完整事件类型枚举""" # 系统事件 SYSTEM_STARTUP = auto() # 系统启动 SYSTEM_SHUTDOWN = auto() # 系统关闭 MODULE_READY = auto() # 模块就绪(替换原来的HEARTBEAT) ERROR = auto() # 错误事件(确保存在) # 业务事件(对应5个核心模块) INPUT_ANALYSIS_START = auto() INPUT_ANALYSIS_END = auto() COMBINATION_ANALYSIS_START = auto() COMBINATION_ANALYSIS_END = auto() FOLLOW_ANALYSIS_START = auto() FOLLOW_ANALYSIS_UPDATE = auto() TREND_ANALYSIS_REQUEST = auto() TREND_ANALYSIS_REPORT = auto() NUMBER_GENERATION_START = auto() NUMBER_GENERATION_FINISH = auto() # 测试事件 TEST_EVENT = auto() # 专门用于测试的事件类型 @dataclass class Event: """事件数据类(优化验证逻辑)""" type: Union[str, EventType] source: str event_id: str = field(default_factory=lambda: str(uuid.uuid4())) target: Optional[str] = None data: Optional[Dict[str, Any]] = field(default_factory=dict) token: Optional[str] = None timestamp: float = field(default_factory=time.time) def __post_init__(self): """数据验证方法(优化验证逻辑)""" self.type = self.type.value if isinstance(self.type, EventType) else self.type if not isinstance(self.type, str) or not self.type: raise ValueError("type 必须是非空字符串或EventType枚举") if not isinstance(self.source, str) or not self.source: raise ValueError("source 必须是非空字符串") if self.target is not None and not isinstance(self.target, str): raise ValueError("target 必须是字符串或None") if not isinstance(self.data, dict): raise ValueError("data 必须是字典") class EventCenter: """线程安全的高性能事件中心单例""" _instance = None _lock = threading.Lock() _executor = ThreadPoolExecutor(max_workers=10, thread_name_prefix="EventWorker") def __new__(cls): with cls._lock: if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.__initialized = False return cls._instance def __init__(self): if getattr(self, &#39;__initialized&#39;, False): return self.__initialized = True self._lock = threading.RLock() self._subscribers: DefaultDict[str, List[Tuple[Callable[[Event], None], Optional[str]]]] = defaultdict(list) self._event_history: Dict[str, Event] = {} self._pending_acks: Set[str] = set() self._ack_timeout = 5.0 self._event_counter = 0 self._failed_events = 0 logger.info("EventCenter 初始化完成 (线程安全单例)") def subscribe(self, event_type: Union[str, EventType], handler: Callable[[Event], None], token: Optional[str] = None) -> None: """订阅事件(支持EventType枚举和字符串)""" event_type_str = event_type.value if isinstance(event_type, EventType) else event_type if not isinstance(event_type_str, str): raise TypeError("event_type 必须是字符串或EventType枚举") if not callable(handler): raise ValueError("handler 必须是可调用对象") with self._lock: self._subscribers[event_type_str].append((handler, token)) logger.debug("已订阅 %s [token=%s]", event_type_str, token) def publish(self, event: Event, require_ack: bool = False, async_handle: bool = True) -> bool: """发布事件(优化性能和处理逻辑)""" if not isinstance(event, Event): raise TypeError("需要 Event 实例") try: event.__post_init__() except ValueError as e: logger.error("事件验证失败: %s", str(e)) self._failed_events += 1 return False with self._lock: if event.event_id in self._event_history: logger.warning("重复事件 %s", event.event_id[:8]) return False self._event_history[event.event_id] = event self._event_counter += 1 if require_ack: self._pending_acks.add(event.event_id) logger.info("发布 %s 事件 %s (总事件数: %d)", event.type, event.event_id[:8], self._event_counter) handlers = self._get_matching_handlers(event) if async_handle: self._executor.submit(self._dispatch_event, event, handlers, require_ack) else: self._dispatch_event(event, handlers, require_ack) return True def _get_matching_handlers(self, event: Event) -> List[Callable[[Event], None]]: """获取匹配的事件处理器""" with self._lock: return [h for h, t in self._subscribers.get(event.type, []) if t is None or t == event.token] def _dispatch_event(self, event: Event, handlers: List[Callable[[Event], None]], require_ack: bool) -> None: """分发事件(优化错误处理)""" if not handlers: logger.debug("事件 %s 无订阅处理器", event.event_id[:8]) return for handler in handlers: try: start_time = time.perf_counter() handler(event) elapsed = (time.perf_counter() - start_time) * 1000 logger.debug("事件 %s 处理完成 [%s] (耗时 %.2fms)", event.event_id[:8], handler.__name__, elapsed) except Exception as e: logger.exception("处理器 %s 失败: %s", handler.__name__, str(e)) self._publish_error( source="event_center", target=event.source, error=e, context=f"处理 {event.type} 时出错" ) if require_ack and event.target: self._wait_for_ack(event) def _wait_for_ack(self, event: Event) -> None: """等待ACK(优化超时处理)""" start = time.time() while time.time() - start < self._ack_timeout: with self._lock: if event.event_id not in self._pending_acks: logger.debug("收到 %s 的ACK", event.event_id[:8]) return time.sleep(0.05) # 更短的等待间隔 logger.warning("事件 %s 等待ACK超时 (目标: %s)", event.event_id[:8], event.target) self._publish_error( source="event_center", target=event.source, error=TimeoutError(f"ACK超时 ({self._ack_timeout}s)"), context=f"等待 {event.target} 确认超时" ) def acknowledge(self, event_id: str) -> None: """确认事件处理完成(添加锁范围优化)""" with self._lock: if event_id in self._pending_acks: self._pending_acks.remove(event_id) logger.info("收到 %s 的ACK", event_id[:8]) else: logger.warning("无效的ACK: %s (未找到或已处理)", event_id[:8]) def _publish_error(self, source: str, target: str, error: Exception, context: str = "") -> None: """发布错误事件(优化错误信息结构)""" error_event = Event( type=EventType.ERROR, source=source, target=target, data={ "error": str(error), "type": type(error).__name__, "context": context, "stack_trace": logging.getTraceback() } ) self.publish(error_event) def get_stats(self) -> Dict[str, int]: """获取事件中心统计信息(添加更多指标)""" with self._lock: return { "total_events": self._event_counter, "failed_events": self._failed_events, "pending_acks": len(self._pending_acks), "subscriber_types": len(self._subscribers), "active_subscriptions": sum(len(h) for h in self._subscribers.values()), "history_size": len(self._event_history) } def clear_subscriptions(self, event_type: Optional[Union[str, EventType]] = None) -> None: """清除订阅(支持按类型清除)""" with self._lock: if event_type is None: self._subscribers.clear() logger.info("清除所有订阅") else: event_type_str = event_type.value if isinstance(event_type, EventType) else event_type if event_type_str in self._subscribers: del self._subscribers[event_type_str] logger.info("清除 %s 类型的所有订阅", event_type_str) # 单例实例 event_center = EventCenter() # 导出接口 __all__ = [&#39;EventCenter&#39;, &#39;Event&#39;, &#39;EventType&#39;, &#39;event_center&#39;] if __name__ == "__main__": # 模块自测试代码 print("=== EventCenter标准化测试 ===") # 测试处理器 def test_handler(event): print(f"处理标准化测试事件: {event.type} (ID: {event.event_id[:8]})") print(f"事件数据: {event.data}") # 使用标准测试事件类型 event_center.subscribe(EventType.TEST_EVENT, test_handler) # 创建标准测试事件 test_event = Event( type=EventType.TEST_EVENT, source="self_test", data={ "message": "标准化测试事件", "timestamp": time.time() } ) print("发布标准化测试事件...") event_center.publish(test_event) # 等待异步处理完成 time.sleep(0.5) print("自测试完成,退出码: 0")
最新发布
08-10
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值