66using System . Threading . Tasks ;
77using Kscript . CSharp . Parser . Core ;
88using Kscript . CSharp . Parser . Models ;
9+ using KitX . Core . Contract . Plugin ;
910using KitX . Core . Device ;
1011using KitX . Shared . CSharp . Plugin ;
1112using KitX . Shared . CSharp . WebCommand ;
@@ -49,6 +50,38 @@ public RealPluginManager(PluginsServer pluginsServer)
4950
5051 // 订阅插件消息接收事件以处理响应
5152 _pluginsServer . PluginMessageReceived += OnPluginMessageReceived ;
53+
54+ // 订阅插件响应事件(当插件返回带RequestId的响应时触发)
55+ _pluginsServer . PluginResponse += OnPluginResponse ;
56+ }
57+
58+ /// <summary>
59+ /// 处理插件响应事件
60+ /// </summary>
61+ private void OnPluginResponse ( object ? sender , PluginResponseEventArgs e )
62+ {
63+ try
64+ {
65+ Log . Information ( $ "[RealPluginManager] OnPluginResponse called with RequestId: { e . RequestId } ") ;
66+
67+ if ( _pendingResponses . TryRemove ( e . RequestId , out var tcs ) )
68+ {
69+ var command = JsonSerializer . Deserialize < Command > ( e . Content , _serializerOptions ) ;
70+ var responseBody = command . BodyLength > 0
71+ ? Encoding . UTF8 . GetString ( command . Body . AsSpan ( 0 , command . BodyLength ) )
72+ : string . Empty ;
73+ Log . Information ( $ "[RealPluginManager] Setting result from PluginResponse: { responseBody } ") ;
74+ tcs . SetResult ( responseBody ) ;
75+ }
76+ else
77+ {
78+ Log . Warning ( $ "[RealPluginManager] RequestId { e . RequestId } not found in pending responses") ;
79+ }
80+ }
81+ catch ( Exception ex )
82+ {
83+ Log . Warning ( ex , "[RealPluginManager] Error handling plugin response" ) ;
84+ }
5285 }
5386
5487 /// <summary>
@@ -58,22 +91,36 @@ private void OnPluginMessageReceived(object? sender, PluginMessageReceivedEventA
5891 {
5992 try
6093 {
94+ Log . Information ( $ "[RealPluginManager] OnPluginMessageReceived called with message: { e . Message ? . Substring ( 0 , Math . Min ( 200 , e . Message ? . Length ?? 0 ) ) } ...") ;
95+
6196 var kwc = JsonSerializer . Deserialize < Request > ( e . Message , _serializerOptions ) ;
62- if ( kwc ? . Content is null ) return ;
97+ if ( kwc ? . Content is null )
98+ {
99+ Log . Information ( $ "[RealPluginManager] kwc or kwc.Content is null") ;
100+ return ;
101+ }
102+
103+ Log . Information ( $ "[RealPluginManager] kwc.Content: { kwc . Content . Substring ( 0 , Math . Min ( 100 , kwc . Content . Length ) ) } ...") ;
63104
64105 var command = JsonSerializer . Deserialize < Command > ( kwc . Content , _serializerOptions ) ;
65106 if ( command . Request is null ) return ; // Command is a struct, check if Request is empty
66107
67108 // 检查是否是响应消息
68109 if ( command . Tags != null && command . Tags . TryGetValue ( "RequestId" , out var requestId ) )
69110 {
111+ Log . Information ( $ "[RealPluginManager] Found RequestId: { requestId } ") ;
70112 if ( _pendingResponses . TryRemove ( requestId , out var tcs ) )
71113 {
72114 var responseBody = command . BodyLength > 0
73115 ? Encoding . UTF8 . GetString ( command . Body . AsSpan ( 0 , command . BodyLength ) )
74116 : string . Empty ;
117+ Log . Information ( $ "[RealPluginManager] Setting result: { responseBody } ") ;
75118 tcs . SetResult ( responseBody ) ;
76119 }
120+ else
121+ {
122+ Log . Warning ( $ "[RealPluginManager] RequestId { requestId } not found in pending responses") ;
123+ }
77124 }
78125 }
79126 catch ( Exception ex )
@@ -178,10 +225,24 @@ private async Task<string> CallAsync(PluginCallInfo callInfo)
178225
179226 Log . Information ( $ "[RealPluginManager] Sent request to { callInfo . PluginName } .{ callInfo . MethodName } , RequestId: { requestId } ") ;
180227
181- // 注意: Loader 在处理 ReceiveCommand 后不会返回响应
182- // 对于 void 方法,我们直接返回空结果
183- // 对于有返回值的方法,需要插件支持返回响应(当前不支持)
184- return string . Empty ;
228+ // 等待插件响应,设置超时
229+ using var cts = new CancellationTokenSource ( TimeSpan . FromSeconds ( 30 ) ) ;
230+ try
231+ {
232+ return await tcs . Task . WaitAsync ( cts . Token ) ;
233+ }
234+ catch ( TimeoutException )
235+ {
236+ Log . Warning ( $ "[RealPluginManager] Request { requestId } timed out") ;
237+ _pendingResponses . TryRemove ( requestId , out _ ) ;
238+ throw new TimeoutException ( $ "Plugin call timed out: { callInfo . PluginName } .{ callInfo . MethodName } ") ;
239+ }
240+ catch ( OperationCanceledException )
241+ {
242+ Log . Warning ( $ "[RealPluginManager] Request { requestId } was cancelled") ;
243+ _pendingResponses . TryRemove ( requestId , out _ ) ;
244+ throw ;
245+ }
185246 }
186247 catch ( Exception ex )
187248 {
0 commit comments