< Summary - ReFlex - Library

Information
Class: ReFlex.Core.Tuio.Components.TuioSender
Assembly: ReFlex.Core.Tuio
File(s): D:\a\reflex\reflex\library\src\Core\Tuio\Components\TuioSender.cs
Line coverage
70%
Covered lines: 87
Uncovered lines: 36
Coverable lines: 123
Total lines: 244
Line coverage: 70.7%
Branch coverage
85%
Covered branches: 46
Total branches: 54
Branch coverage: 85.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
get_IsInitialized()100%11100%
Initialize(...)100%1414100%
SendUdp()100%22100%
SendTcp()80%1010100%
SendWebSocket()83.33%1212100%
SendOscMessageUdp()100%210%
SendOscMessageTcp()0%620%
SendOscMessageWebSocket()0%620%
StopAllConnections()100%1212100%

File(s)

D:\a\reflex\reflex\library\src\Core\Tuio\Components\TuioSender.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3using System.Net.Sockets;
 4using System.Net.WebSockets;
 5using System.Runtime.Serialization.Formatters.Binary;
 6using System.Threading;
 7using System.Threading.Tasks;
 8using CoreOSC;
 9using CoreOSC.IO;
 10using NLog;
 11using ReFlex.Core.Common.Adapter;
 12using ReFlex.Core.Common.Interfaces;
 13using ReFlex.Core.Tuio.Interfaces;
 14using ReFlex.Core.Tuio.Util;
 15
 16namespace ReFlex.Core.Tuio.Components
 17{
 18    public class TuioSender : ITuioSender
 19    {
 120        private static readonly Logger Log = LogManager.GetCurrentClassLogger();
 21
 22        /// <summary>
 23        /// Client for sending TUIO Messages to Server using UDP
 24        /// </summary>
 25        protected UdpClient UdpClient;
 26
 27        /// <summary>
 28        /// Client Interface for sending TUIO Messages to Server using TCP. (use <see cref="TcpClientAdapter"/> for bett
 29        /// </summary>
 30        protected ITcpClient TcpClient;
 31
 32        /// <summary>
 33        /// Client Interface for sending TUIO Messages to Server using WebSocket protocol. (use <see cref="ClientWebSock
 34        /// </summary>
 35        protected IClientWebSocket WsClient;
 36
 37        private string _serverAddress;
 38        private int _serverPort;
 39
 40        /// <summary>
 41        /// Specifies whether a valid <see cref="TuioConfiguration"/> has been provided and sending is enabled.
 42        /// </summary>
 6243        public bool IsInitialized { get; protected set; }
 44
 45        /// <summary>
 46        /// Initializes communication by instantiating clients and setting server address and port.
 47        /// If config has a valid <see cref="TransportProtocol"/> and server address and port are formally valid, <see c
 48        /// </summary>
 49        /// <param name="config"><see cref="TuioConfiguration"/> specifying <see cref="TransportProtocol"/>, server addr
 50        /// <exception cref="ArgumentException">if provided <see cref="TransportProtocol"/> has an invalid value (neithe
 51        public virtual void Initialize(TuioConfiguration config)
 2152        {
 2153            if (config == null || string.IsNullOrWhiteSpace(config.ServerAddress) || config.ServerPort <= 0)
 554            {
 555                Log.Warn(
 556                    $"Provided invalid value for initializing {nameof(TuioSender)}: Config: {config?.GetTuioConfiguratio
 557                return;
 58            }
 59
 1660            switch (config.Transport)
 61            {
 62                case TransportProtocol.Udp:
 563                    UdpClient = new UdpClient(config.ServerAddress, config.ServerPort);
 564                    break;
 65                case TransportProtocol.Tcp:
 466                    TcpClient = new TcpClientAdapter();
 467                    break;
 68                case TransportProtocol.WebSocket:
 569                    WsClient = new ClientWebSocketAdapter();
 570                    break;
 71                default:
 272                    var msg =
 273                        $"Provided {nameof(TransportProtocol)} ({config.Transport}) is not valid for configuring {nameof
 274                    var exc = new ArgumentException(msg);
 275                    Log.Error(exc, msg);
 276                    throw exc;
 77            }
 78
 1479            _serverAddress = config.ServerAddress;
 1480            _serverPort = config.ServerPort;
 1481            IsInitialized = true;
 1982        }
 83
 84        /// <summary>
 85        /// Send the provided data to the TUIO Server using UDP.
 86        /// </summary>
 87        /// <param name="bundle"><see cref="OscBundle"/> containing valid TUIO messages (Usually constructed by <see cre
 88        public virtual async Task SendUdp(OscBundle bundle)
 289        {
 90            try
 291            {
 1192                foreach (var msg in bundle.Messages)
 393                {
 394                    await SendOscMessageUdp(msg);
 395                }
 196            }
 197            catch (Exception exc)
 198            {
 199                Log.Error(exc, $"Error sending osc message via UDP");
 1100            }
 2101        }
 102
 103        /// <summary>
 104        /// Send the provided data to the TUIO Server using TCP.
 105        /// If not connected, the method connects to the server. If connection is successful, the data is sent
 106        /// </summary>
 107        /// <param name="bundle"><see cref="OscBundle"/> containing valid TUIO messages (Usually constructed by <see cre
 108        public virtual async Task SendTcp(OscBundle bundle)
 4109        {
 4110            if (TcpClient?.Connected == false)
 2111            {
 112                try
 2113                {
 2114                    await TcpClient.ConnectAsync(_serverAddress, _serverPort);
 1115                }
 1116                catch (Exception exc)
 1117                {
 1118                    Log.Error(exc);
 1119                }
 2120            }
 121
 4122            if (TcpClient?.Connected == true)
 2123            {
 18124                foreach (var msg in bundle.Messages)
 6125                {
 6126                    await SendOscMessageTcp(msg);
 6127                }
 2128            }
 4129        }
 130
 131        /// <summary>
 132        /// Send the provided data to the TUIO Server using WebSocket protocol.
 133        /// If Websocket status is not <see cref="WebSocketState.Open"/>, the method (re)connects to the server.
 134        /// If connection is successful, the data is sent.
 135        /// </summary>
 136        /// <param name="bundle"><see cref="OscBundle"/> containing valid TUIO messages (Usually constructed by <see cre
 137        public virtual async Task SendWebSocket(OscBundle bundle)
 4138        {
 4139            if (WsClient?.State != WebSocketState.Open)
 2140            {
 2141                var uri = new Uri($"ws://{_serverAddress}:{_serverPort}");
 142                try
 2143                {
 2144                    if (WsClient != null)
 2145                        await WsClient.ConnectAsync(uri, CancellationToken.None);
 1146                }
 1147                catch (Exception exc)
 1148                {
 1149                    Log.Error(exc);
 1150                }
 2151            }
 152
 4153            if (WsClient?.State == WebSocketState.Open)
 2154            {
 28155                foreach (var msg in bundle.Messages)
 11156                {
 11157                    await SendOscMessageWebSocket(msg);
 11158                }
 2159            }
 4160        }
 161
 162        /// <summary>
 163        /// Wrapper method for sending messages (protected to be overridden in test classes)
 164        /// </summary>
 165        /// <param name="msg"><see cref="OscMessage"/> to be transmitted</param>
 166        protected virtual async Task SendOscMessageUdp(OscMessage msg)
 0167        {
 0168            await UdpClient.SendMessageAsync(msg);
 0169        }
 170
 171        /// <summary>
 172        /// Wrapper method for sending messages (protected to be overridden in test classes).
 173        /// Provided message is binary formatted using <see cref="BinaryFormatter"/> and written to TCP Stream.
 174        /// </summary>
 175        /// <param name="msg"><see cref="OscMessage"/> to be transmitted</param>
 176        protected virtual async Task SendOscMessageTcp(OscMessage msg)
 0177        {
 0178            var format = new BinaryFormatter();
 179            try
 0180            {
 181
 0182                format.Serialize(TcpClient.GetStream(), msg.Address.Value);
 183
 0184                foreach (var arg in msg.Arguments)
 0185                {
 0186                    format.Serialize(TcpClient.GetStream(), arg);
 0187                }
 188
 0189                await TcpClient.GetStream().FlushAsync();
 0190            }
 0191            catch (Exception exc)
 0192            {
 0193                Log.Error(exc);
 0194            }
 0195        }
 196
 197        /// <summary>
 198        /// Wrapper method for sending messages (protected to be overridden in test classes).
 199        /// Provided message is binary formatted using <see cref="BinaryFormatter"/> and
 200        /// written to <see cref="MemoryStream"/> which in turn is sent asynchronously via Websockets.
 201        /// </summary>
 202        /// <param name="msg"><see cref="OscMessage"/> to be transmitted</param>
 203        protected virtual async Task SendOscMessageWebSocket(OscMessage msg)
 0204        {
 0205            var mStream = new MemoryStream();
 0206            var format = new BinaryFormatter();
 0207            format.Serialize(mStream, msg.Address.Value);
 0208            foreach (var arg in msg.Arguments)
 0209            {
 0210                format.Serialize(mStream, arg);
 0211            }
 212
 213            try
 0214            {
 0215                await WsClient.SendAsync(new ArraySegment<byte>(mStream.ToArray()),
 0216                    WebSocketMessageType.Binary, true,
 0217                    CancellationToken.None);
 0218            }
 0219            catch (Exception exc)
 0220            {
 0221                Log.Error(exc);
 0222            }
 0223        }
 224
 225        /// <summary>
 226        /// Closes and disposes all clients (if initialized).
 227        /// Resets <see cref="IsInitialized"/> to false.
 228        /// </summary>
 229        public virtual async Task StopAllConnections()
 3230        {
 3231            UdpClient?.Close();
 3232            TcpClient?.Close();
 3233            if (WsClient != null)
 1234                await WsClient.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close connection",
 1235                    CancellationToken.None);
 236
 3237            UdpClient?.Dispose();
 3238            TcpClient?.Dispose();
 3239            WsClient?.Dispose();
 240
 3241            IsInitialized = false;
 3242        }
 243    }
 244}