diff --git a/CHANGES.md b/CHANGES.md index ba43fe52fd..80dd36b156 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -49,7 +49,8 @@ To be released. duplicated transaction ids. [[#366]] - Fixed a bug that `NullReferenceException` occurred when serializing default `Address`. [[#369]] - + - Fixed a bug that `TurnClient` throws `KeyNotFoundException` and + `IOException` when startup. [[#377], [#378]] [#319]: https://github.com/planetarium/libplanet/issues/319 [#343]: https://github.com/planetarium/libplanet/pull/343 @@ -59,6 +60,8 @@ To be released. [#366]: https://github.com/planetarium/libplanet/pull/366 [#367]: https://github.com/planetarium/libplanet/pull/367 [#369]: https://github.com/planetarium/libplanet/pull/369 +[#377]: https://github.com/planetarium/libplanet/issues/377 +[#378]: https://github.com/planetarium/libplanet/pull/378 Version 0.4.1 diff --git a/Libplanet.Stun/Stun/TurnClient.cs b/Libplanet.Stun/Stun/TurnClient.cs index 4c168e5474..ed0c2fca0e 100644 --- a/Libplanet.Stun/Stun/TurnClient.cs +++ b/Libplanet.Stun/Stun/TurnClient.cs @@ -70,7 +70,7 @@ public async Task AllocateRequestAsync( { var request = new AllocateRequest((int)lifetime.TotalSeconds); await SendMessageAsync(stream, request, cancellationToken); - response = await _responses[request.TransactionId].Task; + response = await ReceiveMessage(request.TransactionId); if (response is AllocateErrorResponse allocError) { @@ -101,8 +101,7 @@ public async Task CreatePermissionAsync( NetworkStream stream = _control.GetStream(); var request = new CreatePermissionRequest(peerAddress); await SendMessageAsync(stream, request, cancellationToken); - StunMessage response = - await _responses[request.TransactionId].Task; + StunMessage response = await ReceiveMessage(request.TransactionId); if (response is CreatePermissionErrorResponse) { @@ -154,8 +153,7 @@ public async Task GetMappedAddressAsync( NetworkStream stream = _control.GetStream(); var request = new BindingRequest(); await SendMessageAsync(stream, request, cancellationToken); - StunMessage response = - await _responses[request.TransactionId].Task; + StunMessage response = await ReceiveMessage(request.TransactionId); if (response is BindingSuccessResponse success) { @@ -177,8 +175,7 @@ public async Task RefreshAllocationAsync( var request = new RefreshRequest((int)lifetime.TotalSeconds); await SendMessageAsync(stream, request, cancellationToken); - StunMessage response = - await _responses[request.TransactionId].Task; + StunMessage response = await ReceiveMessage(request.TransactionId); if (response is RefreshSuccessResponse success) { return TimeSpan.FromSeconds(success.Lifetime); @@ -252,7 +249,6 @@ private async Task ProcessMessage() out TaskCompletionSource tcs)) { tcs.SetResult(message); - _responses.Remove(message.TransactionId); } } catch (Exception e) @@ -274,6 +270,14 @@ private async Task EnsureConnection() } } + private async Task ReceiveMessage(byte[] transactionId) + { + StunMessage response = await _responses[transactionId].Task; + _responses.Remove(transactionId); + + return response; + } + private class ByteArrayComparer : IEqualityComparer { public bool Equals(byte[] left, byte[] right)