-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fd048db
commit cc516ef
Showing
68 changed files
with
5,555 additions
and
2 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
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,197 @@ | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
|
||
namespace Hik.Collections | ||
{ | ||
/// <summary> | ||
/// This class is used to store key-value based items in a thread safe manner. | ||
/// It uses System.Collections.Generic.SortedList internally. | ||
/// </summary> | ||
/// <typeparam name="TK">Key type</typeparam> | ||
/// <typeparam name="TV">Value type</typeparam> | ||
public class ThreadSafeSortedList<TK, TV> | ||
{ | ||
/// <summary> | ||
/// Gets/adds/replaces an item by key. | ||
/// </summary> | ||
/// <param name="key">Key to get/set value</param> | ||
/// <returns>Item associated with this key</returns> | ||
public TV this[TK key] | ||
{ | ||
get | ||
{ | ||
_lock.EnterReadLock(); | ||
try | ||
{ | ||
return _items.ContainsKey(key) ? _items[key] : default(TV); | ||
} | ||
finally | ||
{ | ||
_lock.ExitReadLock(); | ||
} | ||
} | ||
|
||
set | ||
{ | ||
_lock.EnterWriteLock(); | ||
try | ||
{ | ||
_items[key] = value; | ||
} | ||
finally | ||
{ | ||
_lock.ExitWriteLock(); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets count of items in the collection. | ||
/// </summary> | ||
public int Count | ||
{ | ||
get | ||
{ | ||
_lock.EnterReadLock(); | ||
try | ||
{ | ||
return _items.Count; | ||
} | ||
finally | ||
{ | ||
_lock.ExitReadLock(); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Internal collection to store items. | ||
/// </summary> | ||
protected readonly SortedList<TK, TV> _items; | ||
|
||
/// <summary> | ||
/// Used to synchronize access to _items list. | ||
/// </summary> | ||
protected readonly ReaderWriterLockSlim _lock; | ||
|
||
/// <summary> | ||
/// Creates a new ThreadSafeSortedList object. | ||
/// </summary> | ||
public ThreadSafeSortedList() | ||
{ | ||
_items = new SortedList<TK, TV>(); | ||
_lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); | ||
} | ||
|
||
/// <summary> | ||
/// Checks if collection contains spesified key. | ||
/// </summary> | ||
/// <param name="key">Key to check</param> | ||
/// <returns>True; if collection contains given key</returns> | ||
public bool ContainsKey(TK key) | ||
{ | ||
_lock.EnterReadLock(); | ||
try | ||
{ | ||
return _items.ContainsKey(key); | ||
} | ||
finally | ||
{ | ||
_lock.ExitReadLock(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Checks if collection contains spesified item. | ||
/// </summary> | ||
/// <param name="item">Item to check</param> | ||
/// <returns>True; if collection contains given item</returns> | ||
public bool ContainsValue(TV item) | ||
{ | ||
_lock.EnterReadLock(); | ||
try | ||
{ | ||
return _items.ContainsValue(item); | ||
} | ||
finally | ||
{ | ||
_lock.ExitReadLock(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Removes an item from collection. | ||
/// </summary> | ||
/// <param name="key">Key of item to remove</param> | ||
public bool Remove(TK key) | ||
{ | ||
_lock.EnterWriteLock(); | ||
try | ||
{ | ||
if (!_items.ContainsKey(key)) | ||
{ | ||
return false; | ||
} | ||
|
||
_items.Remove(key); | ||
return true; | ||
} | ||
finally | ||
{ | ||
_lock.ExitWriteLock(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets all items in collection. | ||
/// </summary> | ||
/// <returns>Item list</returns> | ||
public List<TV> GetAllItems() | ||
{ | ||
_lock.EnterReadLock(); | ||
try | ||
{ | ||
return new List<TV>(_items.Values); | ||
} | ||
finally | ||
{ | ||
_lock.ExitReadLock(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Removes all items from list. | ||
/// </summary> | ||
public void ClearAll() | ||
{ | ||
_lock.EnterWriteLock(); | ||
try | ||
{ | ||
_items.Clear(); | ||
} | ||
finally | ||
{ | ||
_lock.ExitWriteLock(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets then removes all items in collection. | ||
/// </summary> | ||
/// <returns>Item list</returns> | ||
public List<TV> GetAndClearAllItems() | ||
{ | ||
_lock.EnterWriteLock(); | ||
try | ||
{ | ||
var list = new List<TV>(_items.Values); | ||
_items.Clear(); | ||
return list; | ||
} | ||
finally | ||
{ | ||
_lock.ExitWriteLock(); | ||
} | ||
} | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
src/Scs.Core/Communication/Scs/Client/ClientReConnecter.cs
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,110 @@ | ||
using System; | ||
using Hik.Communication.Scs.Communication; | ||
using Hik.Threading; | ||
|
||
namespace Hik.Communication.Scs.Client | ||
{ | ||
/// <summary> | ||
/// This class is used to automatically re-connect to server if disconnected. | ||
/// It attempts to reconnect to server periodically until connection established. | ||
/// </summary> | ||
public class ClientReConnecter : IDisposable | ||
{ | ||
/// <summary> | ||
/// Reconnect check period. | ||
/// Default: 20 seconds. | ||
/// </summary> | ||
public int ReConnectCheckPeriod | ||
{ | ||
get { return _reconnectTimer.Period; } | ||
set { _reconnectTimer.Period = value; } | ||
} | ||
|
||
/// <summary> | ||
/// Reference to client object. | ||
/// </summary> | ||
private readonly IConnectableClient _client; | ||
|
||
/// <summary> | ||
/// Timer to attempt ro reconnect periodically. | ||
/// </summary> | ||
private readonly Timer _reconnectTimer; | ||
|
||
/// <summary> | ||
/// Indicates the dispose state of this object. | ||
/// </summary> | ||
private volatile bool _disposed; | ||
|
||
/// <summary> | ||
/// Creates a new ClientReConnecter object. | ||
/// It is not needed to start ClientReConnecter since it automatically | ||
/// starts when the client disconnected. | ||
/// </summary> | ||
/// <param name="client">Reference to client object</param> | ||
/// <exception cref="ArgumentNullException">Throws ArgumentNullException if client is null.</exception> | ||
public ClientReConnecter(IConnectableClient client) | ||
{ | ||
if (client == null) | ||
{ | ||
throw new ArgumentNullException("client"); | ||
} | ||
|
||
_client = client; | ||
_client.Disconnected += Client_Disconnected; | ||
_reconnectTimer = new Timer(20000); | ||
_reconnectTimer.Elapsed += ReconnectTimer_Elapsed; | ||
_reconnectTimer.Start(); | ||
} | ||
|
||
/// <summary> | ||
/// Disposes this object. | ||
/// Does nothing if already disposed. | ||
/// </summary> | ||
public void Dispose() | ||
{ | ||
if (_disposed) | ||
{ | ||
return; | ||
} | ||
|
||
_disposed = true; | ||
_client.Disconnected -= Client_Disconnected; | ||
_reconnectTimer.Stop(); | ||
} | ||
|
||
/// <summary> | ||
/// Handles Disconnected event of _client object. | ||
/// </summary> | ||
/// <param name="sender">Source of the event</param> | ||
/// <param name="e">Event arguments</param> | ||
private void Client_Disconnected(object sender, EventArgs e) | ||
{ | ||
_reconnectTimer.Start(); | ||
} | ||
|
||
/// <summary> | ||
/// Hadles Elapsed event of _reconnectTimer. | ||
/// </summary> | ||
/// <param name="sender">Source of the event</param> | ||
/// <param name="e">Event arguments</param> | ||
private void ReconnectTimer_Elapsed(object sender, EventArgs e) | ||
{ | ||
if (_disposed || _client.CommunicationState == CommunicationStates.Connected) | ||
{ | ||
_reconnectTimer.Stop(); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
_client.Connect(); | ||
_reconnectTimer.Stop(); | ||
} | ||
catch (Exception exception) | ||
{ | ||
//No need to catch since it will try to re-connect again | ||
System.Diagnostics.Trace.Write($"ReconnectTimer_Elapsed: {exception}"); | ||
} | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/Scs.Core/Communication/Scs/Client/IConnectableClient.cs
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,43 @@ | ||
using System; | ||
using Hik.Communication.Scs.Communication; | ||
|
||
namespace Hik.Communication.Scs.Client | ||
{ | ||
/// <summary> | ||
/// Represents a client for SCS servers. | ||
/// </summary> | ||
public interface IConnectableClient : IDisposable | ||
{ | ||
/// <summary> | ||
/// This event is raised when client connected to server. | ||
/// </summary> | ||
event EventHandler Connected; | ||
|
||
/// <summary> | ||
/// This event is raised when client disconnected from server. | ||
/// </summary> | ||
event EventHandler Disconnected; | ||
|
||
/// <summary> | ||
/// Timeout for connecting to a server (as milliseconds). | ||
/// Default value: 15 seconds (15000 ms). | ||
/// </summary> | ||
int ConnectTimeout { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the current communication state. | ||
/// </summary> | ||
CommunicationStates CommunicationState { get; } | ||
|
||
/// <summary> | ||
/// Connects to server. | ||
/// </summary> | ||
void Connect(); | ||
|
||
/// <summary> | ||
/// Disconnects from server. | ||
/// Does nothing if already disconnected. | ||
/// </summary> | ||
void Disconnect(); | ||
} | ||
} |
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,13 @@ | ||
using Hik.Communication.Scs.Communication; | ||
using Hik.Communication.Scs.Communication.Messengers; | ||
|
||
namespace Hik.Communication.Scs.Client | ||
{ | ||
/// <summary> | ||
/// Represents a client to connect to server. | ||
/// </summary> | ||
public interface IScsClient : IMessenger, IConnectableClient | ||
{ | ||
//Does not define any additional member | ||
} | ||
} |
Oops, something went wrong.