-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from s2quake/fix/callback
Fix an issue where the server is closed
- Loading branch information
Showing
5 changed files
with
239 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// <copyright file="CallbackNoneTest.cs" company="JSSoft"> | ||
// Copyright (c) 2024 Jeesu Choi. All Rights Reserved. | ||
// Licensed under the MIT License. See LICENSE.md in the project root for license information. | ||
// </copyright> | ||
|
||
using JSSoft.Communication.Tests.Extensions; | ||
using Xunit.Abstractions; | ||
|
||
namespace JSSoft.Communication.Tests; | ||
|
||
public class CallbackNoneTest : IAsyncLifetime | ||
{ | ||
private const int Timeout = 3000; | ||
private readonly ITestOutputHelper _logger; | ||
private readonly TestServer1 _testServer = new(); | ||
private readonly ServerContext _serverContext; | ||
private readonly ClientContext _clientContext; | ||
private readonly RandomEndPoint _endPoint = new(); | ||
private ITestService1? _server; | ||
|
||
private Guid _clientToken; | ||
private Guid _serverToken; | ||
|
||
public CallbackNoneTest(ITestOutputHelper logger) | ||
{ | ||
_logger = logger; | ||
_serverContext = new(_testServer) { EndPoint = _endPoint }; | ||
_clientContext = new(new ClientService<ITestService1>()) { EndPoint = _endPoint }; | ||
logger.WriteLine($"{_endPoint}"); | ||
} | ||
|
||
public interface ITestService1 | ||
{ | ||
void Invoke(); | ||
} | ||
|
||
public interface ITestService2 | ||
{ | ||
void Invoke(); | ||
} | ||
|
||
public interface ITestCallback2 | ||
{ | ||
void OnInvoked(); | ||
} | ||
|
||
[Fact] | ||
public void Callback1_Test() | ||
{ | ||
var manualResetEvent = new ManualResetEvent(false); | ||
_clientContext.Disconnected += ClientContext_Disconnected; | ||
_server!.Invoke(); | ||
Assert.False(manualResetEvent.WaitOne(Timeout)); | ||
|
||
void ClientContext_Disconnected(object? sender, EventArgs e) | ||
{ | ||
manualResetEvent.Set(); | ||
} | ||
} | ||
|
||
public async Task InitializeAsync() | ||
{ | ||
_serverToken = await _serverContext.OpenAsync(CancellationToken.None); | ||
_logger.WriteLine($"Server is opened: {_serverToken}"); | ||
_clientToken = await _clientContext.OpenAsync(CancellationToken.None); | ||
_logger.WriteLine($"Client is opened: {_clientToken}"); | ||
_server = _testServer; | ||
} | ||
|
||
public async Task DisposeAsync() | ||
{ | ||
await _serverContext.ReleaseAsync(_serverToken); | ||
_logger.WriteLine($"Server is released: {_serverToken}"); | ||
await _clientContext.ReleaseAsync(_clientToken); | ||
_logger.WriteLine($"Client is released: {_clientToken}"); | ||
_endPoint.Dispose(); | ||
} | ||
|
||
private sealed class TestServer1 : ServerService<ITestService1, ITestCallback2>, ITestService1 | ||
{ | ||
public void Invoke() => Client.OnInvoked(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// <copyright file="EventObjectCollection.cs" company="JSSoft"> | ||
// Copyright (c) 2024 Jeesu Choi. All Rights Reserved. | ||
// Licensed under the MIT License. See LICENSE.md in the project root for license information. | ||
// </copyright> | ||
|
||
namespace JSSoft.Communication.Tests; | ||
|
||
public sealed class EventObjectCollection<TObject, TEventArgs> | ||
: Dictionary<TObject, ManualResetEvent>, IDisposable | ||
where TObject : notnull | ||
where TEventArgs : EventArgs | ||
{ | ||
private readonly Action<TObject, EventHandler<TEventArgs>> _detach; | ||
|
||
public EventObjectCollection( | ||
TObject[] items, | ||
Action<TObject, EventHandler<TEventArgs>> attach, | ||
Action<TObject, EventHandler<TEventArgs>> detach) | ||
: base(capacity: items.Length) | ||
{ | ||
for (var i = 0; i < items.Length; i++) | ||
{ | ||
Add(items[i], new ManualResetEvent(initialState: false)); | ||
attach(items[i], Handler); | ||
} | ||
|
||
_detach = detach; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
foreach (var item in this) | ||
{ | ||
_detach(item.Key, Handler); | ||
item.Value.Dispose(); | ||
} | ||
} | ||
|
||
public async Task<int> WaiyAsync(int timeout) | ||
{ | ||
var tasks = Values.Select(item => Task.Run(() => item.WaitOne(timeout))); | ||
var results = await Task.WhenAll(tasks); | ||
return results.Count(item => item == true); | ||
} | ||
|
||
private void Handler(object? s, TEventArgs args) | ||
{ | ||
if (s is TObject item && TryGetValue(item, out var manualResetEvent) == true) | ||
{ | ||
manualResetEvent.Set(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters