diff --git a/src/libnpsharp/NPClient.cs b/src/libnpsharp/NPClient.cs index f2d99db..53e9d91 100644 --- a/src/libnpsharp/NPClient.cs +++ b/src/libnpsharp/NPClient.cs @@ -117,7 +117,7 @@ namespace NPSharp LoginId = result.NPID; SessionToken = result.SessionToken; tcs.SetResult(true); - }); + }, 10); _rpc.Send(new AuthenticateWithTokenMessage {Token = token}); return await tcs.Task; @@ -140,7 +140,7 @@ namespace NPSharp if (result.Result != 0) tcs.SetResult(false); tcs.SetResult(true); - }); + }, 10); _rpc.Send(new StorageWriteUserFileMessage {FileData = contents, FileName = filename, NPID = LoginId}); return await tcs.Task; @@ -164,7 +164,7 @@ namespace NPSharp return; } tcs.SetResult(result.FileData); - }); + }, 10); _rpc.Send(new StorageGetUserFileMessage {FileName = filename, NPID = LoginId}); return await tcs.Task; @@ -202,7 +202,7 @@ namespace NPSharp return; } tcs.SetResult(result.FileData); - }); + }, 10); _rpc.Send(new StorageGetPublisherFileMessage {FileName = filename}); return await tcs.Task; diff --git a/src/libnpsharp/RPC/RPCClientStream.cs b/src/libnpsharp/RPC/RPCClientStream.cs index e594fcf..b1d270f 100644 --- a/src/libnpsharp/RPC/RPCClientStream.cs +++ b/src/libnpsharp/RPC/RPCClientStream.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.Sockets; using log4net; using NPSharp.RPC.Messages; @@ -18,7 +19,7 @@ namespace NPSharp.RPC private readonly string _host; private readonly ushort _port; - private readonly Dictionary> _callbacks = new Dictionary>(); + private readonly Dictionary>> _callbacks = new Dictionary>>(); /// /// Initializes an RPC connection stream with a specified host and port. @@ -71,6 +72,7 @@ namespace NPSharp.RPC try { + _callbacks.Clear(); _ns.Close(timeout); _ns.Dispose(); } @@ -84,12 +86,14 @@ namespace NPSharp.RPC /// Attaches a callback to the next message being sent out. This allows handling response packets. /// /// The method to call when we receive a response to the next message - public void AttachCallback(Action callback) + /// Time in seconds from now in which this callback will expire for the next packet + public void AttachCallback(Action callback, double timeout) { + _cleanupCallbacks(); _log.DebugFormat("AttachCallback for packet id {0}", _id); if (_callbacks.ContainsKey(_id)) throw new Exception("There is already a callback for the current message. You can only add max. one callback."); - _callbacks.Add(_id, callback); + _callbacks.Add(_id, new Tuple>(DateTime.Now + TimeSpan.FromSeconds(timeout), callback)); } // TODO: Exposure of message ID needed or no? @@ -130,15 +134,21 @@ namespace NPSharp.RPC return null; } - _log.DebugFormat("Received packet ID {1} (type {0})", message.GetType().Name, message.MessageId); - if (!_callbacks.ContainsKey(message.MessageId)) return message; - _callbacks[message.MessageId].Invoke(message); - // TODO: Callback cleanup + _cleanupCallbacks(); + if (_callbacks.ContainsKey(message.MessageId)) + _callbacks[message.MessageId].Item2.Invoke(message); return message; } + + private void _cleanupCallbacks() + { + var cbr = (from item in _callbacks where item.Value.Item1 < DateTime.Now select item.Key).ToArray(); + foreach (var cb in cbr) + _callbacks.Remove(cb); + } } }