11using System ;
22using System . Collections . Generic ;
3- using System . Threading . Tasks ;
3+ using System . Threading ;
4+ using Cysharp . Threading . Tasks ;
45using Google . Protobuf ;
56
67namespace WebViewRPC
@@ -12,9 +13,9 @@ public class WebViewRpcClient : IDisposable
1213 {
1314 private readonly IWebViewBridge _bridge ;
1415
15- // Mapping RequestId -> TaskCompletionSource
16- private readonly Dictionary < string , TaskCompletionSource < RpcEnvelope > > _pendingRequests
17- = new Dictionary < string , TaskCompletionSource < RpcEnvelope > > ( ) ;
16+ // Mapping RequestId -> UniTaskCompletionSource
17+ private readonly Dictionary < string , UniTaskCompletionSource < RpcEnvelope > > _pendingRequests
18+ = new Dictionary < string , UniTaskCompletionSource < RpcEnvelope > > ( ) ;
1819
1920 private bool _disposed ;
2021
@@ -29,44 +30,57 @@ public WebViewRpcClient(IWebViewBridge bridge)
2930 /// User should not call this method directly.
3031 /// Instead, use generated method from .proto file.
3132 /// </summary>
32- public async Task < TResponse > CallMethodAsync < TResponse > ( string methodName , IMessage request )
33+ public async UniTask < TResponse > CallMethodAsync < TResponse > ( string methodName , IMessage request , CancellationToken cancellationToken = default )
3334 where TResponse : IMessage < TResponse > , new ( )
3435 {
3536 if ( _disposed ) throw new ObjectDisposedException ( nameof ( WebViewRpcClient ) ) ;
3637
3738 var requestId = Guid . NewGuid ( ) . ToString ( "N" ) ;
3839
39- var tcs = new TaskCompletionSource < RpcEnvelope > ( ) ;
40+ var utcs = new UniTaskCompletionSource < RpcEnvelope > ( ) ;
4041 lock ( _pendingRequests )
4142 {
42- _pendingRequests [ requestId ] = tcs ;
43+ _pendingRequests [ requestId ] = utcs ;
4344 }
4445
45- // (Protobuf -> byte[] -> Base64)
46- var requestBytes = request . ToByteArray ( ) ;
47- var env = new RpcEnvelope
46+ // Handle cancellation
47+ using ( cancellationToken . Register ( ( ) =>
4848 {
49- RequestId = requestId ,
50- IsRequest = true ,
51- Method = methodName ,
52- Payload = ByteString . CopyFrom ( requestBytes )
53- } ;
54- var envBytes = env . ToByteArray ( ) ;
55- var envBase64 = Convert . ToBase64String ( envBytes ) ;
56-
57- // Send to WebView
58- _bridge . SendMessageToWeb ( envBase64 ) ;
59-
60- var responseEnv = await tcs . Task ;
61- if ( ! string . IsNullOrEmpty ( responseEnv . Error ) )
49+ lock ( _pendingRequests )
50+ {
51+ if ( _pendingRequests . Remove ( requestId , out var cancelled ) )
52+ {
53+ cancelled . TrySetCanceled ( ) ;
54+ }
55+ }
56+ } ) )
6257 {
63- throw new Exception ( $ "RPC Error: { responseEnv . Error } ") ;
64- }
58+ // (Protobuf -> byte[] -> Base64)
59+ var requestBytes = request . ToByteArray ( ) ;
60+ var env = new RpcEnvelope
61+ {
62+ RequestId = requestId ,
63+ IsRequest = true ,
64+ Method = methodName ,
65+ Payload = ByteString . CopyFrom ( requestBytes )
66+ } ;
67+ var envBytes = env . ToByteArray ( ) ;
68+ var envBase64 = Convert . ToBase64String ( envBytes ) ;
6569
66- // Payload -> TResponse
67- var resp = new TResponse ( ) ;
68- resp . MergeFrom ( responseEnv . Payload ) ;
69- return resp ;
70+ // Send to WebView
71+ _bridge . SendMessageToWeb ( envBase64 ) ;
72+
73+ var responseEnv = await utcs . Task ;
74+ if ( ! string . IsNullOrEmpty ( responseEnv . Error ) )
75+ {
76+ throw new Exception ( $ "RPC Error: { responseEnv . Error } ") ;
77+ }
78+
79+ // Payload -> TResponse
80+ var resp = new TResponse ( ) ;
81+ resp . MergeFrom ( responseEnv . Payload ) ;
82+ return resp ;
83+ }
7084 }
7185
7286 private void OnBridgeMessage ( string base64 )
@@ -91,14 +105,14 @@ private void OnBridgeMessage(string base64)
91105
92106 private void HandleResponse ( RpcEnvelope env )
93107 {
94- TaskCompletionSource < RpcEnvelope > tcs = null ;
108+ UniTaskCompletionSource < RpcEnvelope > utcs = null ;
95109 lock ( _pendingRequests )
96110 {
97- _pendingRequests . Remove ( env . RequestId , out tcs ) ;
111+ _pendingRequests . Remove ( env . RequestId , out utcs ) ;
98112 }
99- if ( tcs != null )
113+ if ( utcs != null )
100114 {
101- tcs . TrySetResult ( env ) ;
115+ utcs . TrySetResult ( env ) ;
102116 }
103117 }
104118
0 commit comments