Skip to content

Commit 1a9be2d

Browse files
authored
Merge pull request #18 from Three-Byte/addsdatagetter
adds get data
2 parents 866209f + 254d159 commit 1a9be2d

2 files changed

Lines changed: 89 additions & 54 deletions

File tree

ThreeByte.LinkLib/ThreeByte.LinkLib.Shared/Logging/LogFactory.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
namespace ThreeByte.LinkLib.Shared.Logging
44
{
5+
6+
/// <summary>
7+
/// Factory for creating loggers
8+
/// </summary>
59
public class LogFactory
610
{
711
public static ILogger Create<T>()

ThreeByte.LinkLib/ThreeByte.LinkLib.TcpLink/AsyncTcpLink.cs

Lines changed: 85 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,29 @@
1-
using Microsoft.Extensions.Logging;
21
using System;
32
using System.Collections.Generic;
43
using System.Net.Sockets;
54
using System.Threading;
5+
using Microsoft.Extensions.Logging;
66
using ThreeByte.LinkLib.Shared.Logging;
77

88
namespace ThreeByte.LinkLib.TcpLink
99
{
1010
public class AsyncTcpLink : IDisposable
1111
{
12-
public event EventHandler<bool>? IsConnectedChanged;
13-
public event EventHandler<bool>? IsEnabledChanged;
14-
public event EventHandler<Exception>? ErrorOccurred;
15-
public event EventHandler? DataReceived;
16-
public bool IsConnected => _isConnected;
17-
public bool IsEnabled => _isEnabled;
18-
public string Address => _settings.Address;
19-
public int Port => _settings.Port;
20-
public bool HasData => _incomingData.Count > 0;
21-
2212
private const int BufferSize = 8092;
2313
private const int MaxDataSize = 100;
24-
25-
private readonly TcpLinkSettings _settings;
2614
private readonly ILogger _logger;
2715

28-
private bool _isEnabled = true;
29-
private bool _isDisposed = false;
30-
private bool _isConnected = false;
31-
private List<byte[]> _incomingData = new List<byte[]>();
32-
private object _clientLock = new object();
16+
private readonly TcpLinkSettings _settings;
17+
private readonly object _clientLock = new object();
3318
private IAsyncResult? _connectResult;
19+
private readonly List<byte[]> _incomingData = new List<byte[]>();
20+
private bool _isDisposed;
21+
22+
private NetworkStream? _networkStream;
3423
private IAsyncResult? _readResult;
35-
private IAsyncResult? _writeResult;
3624

3725
private TcpClient? _tcpClient;
38-
private NetworkStream? _networkStream;
26+
private IAsyncResult? _writeResult;
3927

4028
public AsyncTcpLink(string address, int port)
4129
: this(address, port, true)
@@ -45,7 +33,7 @@ public AsyncTcpLink(string address, int port)
4533
public AsyncTcpLink(string address, int port, bool enabled = true)
4634
{
4735
_settings = new TcpLinkSettings(address, port);
48-
_isEnabled = enabled;
36+
IsEnabled = enabled;
4937
_logger = LogFactory.Create<AsyncTcpLink>();
5038

5139
if (enabled)
@@ -54,19 +42,49 @@ public AsyncTcpLink(string address, int port, bool enabled = true)
5442
}
5543
}
5644

45+
public bool IsConnected { get; private set; }
46+
47+
public bool IsEnabled { get; private set; } = true;
48+
49+
public string Address => _settings.Address;
50+
public int Port => _settings.Port;
51+
public bool HasData => _incomingData.Count > 0;
52+
53+
/// <summary>
54+
/// Cancels the thread and releases resources.
55+
/// Clients of this class are responsible for calling it.
56+
/// </summary>
57+
public void Dispose()
58+
{
59+
if (_isDisposed)
60+
{
61+
return;
62+
}
63+
64+
_isDisposed = true;
65+
_logger.LogInformation("Cleaning up network resources.");
66+
67+
SafeClose();
68+
}
69+
70+
public event EventHandler<bool>? IsConnectedChanged;
71+
public event EventHandler<bool>? IsEnabledChanged;
72+
public event EventHandler<Exception>? ErrorOccurred;
73+
public event EventHandler? DataReceived;
74+
5775
/// <summary>
58-
/// Sets a value indicating whether messages should be propagated to the network or not
76+
/// Sets a value indicating whether messages should be propagated to the network or not
5977
/// </summary>
6078
/// <param name="value"></param>
6179
public void SetEnabled(bool value)
6280
{
63-
_isEnabled = value;
81+
IsEnabled = value;
6482

65-
if (!_isEnabled)
83+
if (!IsEnabled)
6684
{
6785
SafeClose();
6886
}
69-
else if (!_isConnected)
87+
else if (!IsConnected)
7088
{
7189
SafeConnect();
7290
}
@@ -75,12 +93,12 @@ public void SetEnabled(bool value)
7593
}
7694

7795
/// <summary>
78-
/// Asynchronously sends the TCP message, waiting until the connection is reestablihsed if necessary
96+
/// Asynchronously sends the TCP message, waiting until the connection is reestablihsed if necessary
7997
/// </summary>
8098
/// <param name="message">binary message to be sent</param>
8199
public void SendMessage(byte[] message)
82100
{
83-
if (!_isEnabled)
101+
if (!IsEnabled)
84102
{
85103
return;
86104
}
@@ -111,24 +129,7 @@ public void SendMessage(byte[] message)
111129
}
112130

113131
/// <summary>
114-
/// Cancels the thread and releases resources.
115-
/// Clients of this class are responsible for calling it.
116-
/// </summary>
117-
public void Dispose()
118-
{
119-
if (_isDisposed)
120-
{
121-
return;
122-
}
123-
124-
_isDisposed = true;
125-
_logger.LogInformation("Cleaning up network resources.");
126-
127-
SafeClose();
128-
}
129-
130-
/// <summary>
131-
/// Very carefully checks and shuts down the tcpClient and sets it to null
132+
/// Very carefully checks and shuts down the tcpClient and sets it to null
132133
/// </summary>
133134
private void SafeClose()
134135
{
@@ -175,7 +176,7 @@ private void SafeConnect(object state)
175176
}
176177

177178
/// <summary>
178-
/// Carefully check to see if the link is connected or can be reestablished
179+
/// Carefully check to see if the link is connected or can be reestablished
179180
/// </summary>
180181
private void SafeConnect()
181182
{
@@ -236,7 +237,8 @@ private void ConnectCallback(IAsyncResult asyncResult)
236237
{
237238
ChangeIsConnected(false);
238239
}
239-
if (!_isEnabled)
240+
241+
if (!IsEnabled)
240242
{
241243
SafeClose();
242244
}
@@ -252,9 +254,9 @@ private void ConnectCallback(IAsyncResult asyncResult)
252254
_logger.LogDebug("Clearing Connect Result.");
253255
_connectResult = null;
254256

255-
if (_isEnabled)
257+
if (IsEnabled)
256258
{
257-
if (!_isConnected)
259+
if (!IsConnected)
258260
{
259261
Timer timer = new Timer(
260262
SafeConnect,
@@ -296,7 +298,7 @@ private void WriteCallback(IAsyncResult asyncResult)
296298

297299
private void ReceiveData()
298300
{
299-
if (!_isEnabled)
301+
if (!IsEnabled)
300302
{
301303
return;
302304
}
@@ -362,7 +364,6 @@ private void ReadCallback(IAsyncResult asyncResult)
362364

363365
ChangeIsConnected(true);
364366
}
365-
366367
}
367368
catch (Exception ex)
368369
{
@@ -386,16 +387,46 @@ private void ReadCallback(IAsyncResult asyncResult)
386387
ReceiveData();
387388
}
388389

390+
/// <summary>
391+
/// Fetches and removes (pops) the next available group of bytes as received on this link in order (FIFO)
392+
/// </summary>
393+
/// <returns>null if the link is not Enabled or there is no data currently queued to return, an array of bytes otherwise.</returns>
394+
public byte[] GetMessage()
395+
{
396+
if (_isDisposed)
397+
{
398+
throw new ObjectDisposedException("Cannot get message from disposed NetworkLink");
399+
}
400+
401+
//Return null if the link is not enabled
402+
if (IsEnabled)
403+
{
404+
return null;
405+
}
406+
407+
byte[] newMessage = null;
408+
lock (_incomingData)
409+
{
410+
if (HasData)
411+
{
412+
newMessage = _incomingData[0];
413+
_incomingData.RemoveAt(0);
414+
}
415+
}
416+
417+
return newMessage;
418+
}
419+
389420
private void ChangeIsConnected(bool value)
390421
{
391-
_isConnected = value;
422+
IsConnected = value;
392423
IsConnectedChanged?.Invoke(this, value);
393424
}
394425

395426
private void HandleError(Exception ex, string message)
396427
{
397-
_logger.LogError(exception: ex, message: message);
428+
_logger.LogError(ex, message);
398429
ErrorOccurred?.Invoke(this, ex);
399430
}
400431
}
401-
}
432+
}

0 commit comments

Comments
 (0)