< 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
67%
Covered lines: 89
Uncovered lines: 42
Coverable lines: 131
Total lines: 254
Line coverage: 67.9%
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.Common.Util;
 14using ReFlex.Core.Tuio.Interfaces;
 15using ReFlex.Core.Tuio.Util;
 16
 17namespace ReFlex.Core.Tuio.Components
 18{
 19    public class TuioSender : ITuioSender
 20    {
 121        private static readonly Logger Log = LogManager.GetCurrentClassLogger();
 22
 23        /// <summary>
 24        /// Client for sending TUIO Messages to Server using UDP
 25        /// </summary>
 26        protected UdpClient UdpClient;
 27
 28        /// <summary>
 29        /// Client Interface for sending TUIO Messages to Server using TCP. (use <see cref="TcpClientAdapter"/> for bett
 30        /// </summary>
 31        protected ITcpClient TcpClient;
 32
 33        /// <summary>
 34        /// Client Interface for sending TUIO Messages to Server using WebSocket protocol. (use <see cref="ClientWebSock
 35        /// </summary>
 36        protected IClientWebSocket WsClient;
 37
 38        private string _serverAddress;
 39        private int _serverPort;
 40
 41        /// <summary>
 42        /// Specifies whether a valid <see cref="TuioConfiguration"/> has been provided and sending is enabled.
 43        /// </summary>
 6244        public bool IsInitialized { get; protected set; }
 45
 46        /// <summary>
 47        /// Initializes communication by instantiating clients and setting server address and port.
 48        /// If config has a valid <see cref="TransportProtocol"/> and server address and port are formally valid, <see c
 49        /// </summary>
 50        /// <param name="config"><see cref="TuioConfiguration"/> specifying <see cref="TransportProtocol"/>, server addr
 51        /// <exception cref="ArgumentException">if provided <see cref="TransportProtocol"/> has an invalid value (neithe
 52        public virtual void Initialize(TuioConfiguration config)
 2153        {
 2154            if (config == null || string.IsNullOrWhiteSpace(config.ServerAddress) || config.ServerPort <= 0)
 555            {
 556                Log.Warn(
 557                    $"Provided invalid value for initializing {nameof(TuioSender)}: Config: {config?.GetTuioConfiguratio
 558                return;
 59            }
 60
 1661            switch (config.Transport)
 62            {
 63                case TransportProtocol.Udp:
 564                    UdpClient = new UdpClient(config.ServerAddress, config.ServerPort);
 565                    break;
 66                case TransportProtocol.Tcp:
 467                    TcpClient = new TcpClientAdapter();
 468                    break;
 69                case TransportProtocol.WebSocket:
 570                    WsClient = new ClientWebSocketAdapter();
 571                    break;
 72                default:
 273                    var msg =
 274                        $"Provided {nameof(TransportProtocol)} ({config.Transport}) is not valid for configuring {nameof
 275                    var exc = new ArgumentException(msg);
 276                    Log.Error(exc, msg);
 277                    throw exc;
 78            }
 79
 1480            _serverAddress = config.ServerAddress;
 1481            _serverPort = config.ServerPort;
 1482            LogUtilities.ClearLoggedErrors(nameof(TuioSender));
 1483            IsInitialized = true;
 1984        }
 85
 86        /// <summary>
 87        /// Send the provided data to the TUIO Server using UDP.
 88        /// </summary>
 89        /// <param name="bundle"><see cref="OscBundle"/> containing valid TUIO messages (Usually constructed by <see cre
 90        public virtual async Task SendUdp(OscBundle bundle)
 291        {
 92            try
 293            {
 1994                foreach (var msg in bundle.Messages)
 795                {
 796                    await SendOscMessageUdp(msg);
 797                }
 198            }
 199            catch (Exception exc)
 1100            {
 1101                LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendUdp), "Error sending osc message via UDP")
 1102            }
 2103        }
 104
 105        /// <summary>
 106        /// Send the provided data to the TUIO Server using TCP.
 107        /// If not connected, the method connects to the server. If connection is successful, the data is sent
 108        /// </summary>
 109        /// <param name="bundle"><see cref="OscBundle"/> containing valid TUIO messages (Usually constructed by <see cre
 110        public virtual async Task SendTcp(OscBundle bundle)
 4111        {
 4112            if (TcpClient?.Connected == false)
 2113            {
 114                try
 2115                {
 2116                    await TcpClient.ConnectAsync(_serverAddress, _serverPort);
 1117                }
 1118                catch (Exception exc)
 1119                {
 1120                    LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendTcp));
 1121                }
 2122            }
 123
 4124            if (TcpClient?.Connected == true)
 2125            {
 26126                foreach (var msg in bundle.Messages)
 10127                {
 10128                    await SendOscMessageTcp(msg);
 10129                }
 2130            }
 4131        }
 132
 133        /// <summary>
 134        /// Send the provided data to the TUIO Server using WebSocket protocol.
 135        /// If Websocket status is not <see cref="WebSocketState.Open"/>, the method (re)connects to the server.
 136        /// If connection is successful, the data is sent.
 137        /// </summary>
 138        /// <param name="bundle"><see cref="OscBundle"/> containing valid TUIO messages (Usually constructed by <see cre
 139        public virtual async Task SendWebSocket(OscBundle bundle)
 4140        {
 4141            if (WsClient?.State != WebSocketState.Open)
 2142            {
 2143                var uri = new Uri($"ws://{_serverAddress}:{_serverPort}");
 144                try
 2145                {
 2146                    if (WsClient != null)
 2147                        await WsClient.ConnectAsync(uri, CancellationToken.None);
 1148                }
 1149                catch (Exception exc)
 1150                {
 1151                    LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendWebSocket));
 1152                }
 2153            }
 154
 4155            if (WsClient?.State == WebSocketState.Open)
 2156            {
 32157                foreach (var msg in bundle.Messages)
 13158                {
 13159                    await SendOscMessageWebSocket(msg);
 13160                }
 2161            }
 4162        }
 163
 164        /// <summary>
 165        /// Wrapper method for sending messages (protected to be overridden in test classes)
 166        /// </summary>
 167        /// <param name="msg"><see cref="OscMessage"/> to be transmitted</param>
 168        protected virtual async Task SendOscMessageUdp(OscMessage msg)
 0169        {
 170            try
 0171            {
 0172                await UdpClient.SendMessageAsync(msg);
 0173            }
 0174            catch (Exception exc)
 0175            {
 0176                LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendOscMessageUdp));
 0177            }
 0178        }
 179
 180        /// <summary>
 181        /// Wrapper method for sending messages (protected to be overridden in test classes).
 182        /// Provided message is binary formatted using <see cref="BinaryFormatter"/> and written to TCP Stream.
 183        /// </summary>
 184        /// <param name="msg"><see cref="OscMessage"/> to be transmitted</param>
 185        protected virtual async Task SendOscMessageTcp(OscMessage msg)
 0186        {
 0187            var format = new BinaryFormatter();
 188            try
 0189            {
 190
 0191                format.Serialize(TcpClient.GetStream(), msg.Address.Value);
 192
 0193                foreach (var arg in msg.Arguments)
 0194                {
 0195                    format.Serialize(TcpClient.GetStream(), arg);
 0196                }
 197
 0198                await TcpClient.GetStream().FlushAsync();
 0199            }
 0200            catch (Exception exc)
 0201            {
 0202                LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendOscMessageTcp));
 0203            }
 0204        }
 205
 206        /// <summary>
 207        /// Wrapper method for sending messages (protected to be overridden in test classes).
 208        /// Provided message is binary formatted using <see cref="BinaryFormatter"/> and
 209        /// written to <see cref="MemoryStream"/> which in turn is sent asynchronously via Websockets.
 210        /// </summary>
 211        /// <param name="msg"><see cref="OscMessage"/> to be transmitted</param>
 212        protected virtual async Task SendOscMessageWebSocket(OscMessage msg)
 0213        {
 0214            var mStream = new MemoryStream();
 0215            var format = new BinaryFormatter();
 0216            format.Serialize(mStream, msg.Address.Value);
 0217            foreach (var arg in msg.Arguments)
 0218            {
 0219                format.Serialize(mStream, arg);
 0220            }
 221
 222            try
 0223            {
 0224                await WsClient.SendAsync(new ArraySegment<byte>(mStream.ToArray()),
 0225                    WebSocketMessageType.Binary, true,
 0226                    CancellationToken.None);
 0227            }
 0228            catch (Exception exc)
 0229            {
 0230                LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendOscMessageWebSocket));
 0231            }
 0232        }
 233
 234        /// <summary>
 235        /// Closes and disposes all clients (if initialized).
 236        /// Resets <see cref="IsInitialized"/> to false.
 237        /// </summary>
 238        public virtual async Task StopAllConnections()
 3239        {
 3240            UdpClient?.Close();
 3241            TcpClient?.Close();
 3242            if (WsClient != null)
 1243                await WsClient.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close connection",
 1244                    CancellationToken.None);
 245
 3246            UdpClient?.Dispose();
 3247            TcpClient?.Dispose();
 3248            WsClient?.Dispose();
 3249            LogUtilities.ClearLoggedErrors(nameof(TuioSender));
 250
 3251            IsInitialized = false;
 3252        }
 253    }
 254}