< 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    {
 221        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>
 12444        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)
 4253        {
 4254            if (config == null || string.IsNullOrWhiteSpace(config.ServerAddress) || config.ServerPort <= 0)
 1055            {
 1056                Log.Warn(
 1057                    $"Provided invalid value for initializing {nameof(TuioSender)}: Config: {config?.GetTuioConfiguratio
 1058                return;
 59            }
 60
 3261            switch (config.Transport)
 62            {
 63                case TransportProtocol.Udp:
 1064                    UdpClient = new UdpClient(config.ServerAddress, config.ServerPort);
 1065                    break;
 66                case TransportProtocol.Tcp:
 867                    TcpClient = new TcpClientAdapter();
 868                    break;
 69                case TransportProtocol.WebSocket:
 1070                    WsClient = new ClientWebSocketAdapter();
 1071                    break;
 72                default:
 473                    var msg =
 474                        $"Provided {nameof(TransportProtocol)} ({config.Transport}) is not valid for configuring {nameof
 475                    var exc = new ArgumentException(msg);
 476                    Log.Error(exc, msg);
 477                    throw exc;
 78            }
 79
 2880            _serverAddress = config.ServerAddress;
 2881            _serverPort = config.ServerPort;
 2882            LogUtilities.ClearLoggedErrors(nameof(TuioSender));
 2883            IsInitialized = true;
 3884        }
 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)
 491        {
 92            try
 493            {
 2294                foreach (var msg in bundle.Messages)
 695                {
 696                    await SendOscMessageUdp(msg);
 697                }
 298            }
 299            catch (Exception exc)
 2100            {
 2101                LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendUdp), "Error sending osc message via UDP")
 2102            }
 4103        }
 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)
 8111        {
 8112            if (TcpClient?.Connected == false)
 4113            {
 114                try
 4115                {
 4116                    await TcpClient.ConnectAsync(_serverAddress, _serverPort);
 2117                }
 2118                catch (Exception exc)
 2119                {
 2120                    LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendTcp));
 2121                }
 4122            }
 123
 8124            if (TcpClient?.Connected == true)
 4125            {
 20126                foreach (var msg in bundle.Messages)
 4127                {
 4128                    await SendOscMessageTcp(msg);
 4129                }
 4130            }
 8131        }
 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)
 8140        {
 8141            if (WsClient?.State != WebSocketState.Open)
 4142            {
 4143                var uri = new Uri($"ws://{_serverAddress}:{_serverPort}");
 144                try
 4145                {
 4146                    if (WsClient != null)
 4147                        await WsClient.ConnectAsync(uri, CancellationToken.None);
 2148                }
 2149                catch (Exception exc)
 2150                {
 2151                    LogUtilities.LogErrorOnce(exc, nameof(TuioSender), nameof(SendWebSocket));
 2152                }
 4153            }
 154
 8155            if (WsClient?.State == WebSocketState.Open)
 4156            {
 76157                foreach (var msg in bundle.Messages)
 32158                {
 32159                    await SendOscMessageWebSocket(msg);
 32160                }
 4161            }
 8162        }
 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()
 6239        {
 6240            UdpClient?.Close();
 6241            TcpClient?.Close();
 6242            if (WsClient != null)
 2243                await WsClient.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close connection",
 2244                    CancellationToken.None);
 245
 6246            UdpClient?.Dispose();
 6247            TcpClient?.Dispose();
 6248            WsClient?.Dispose();
 6249            LogUtilities.ClearLoggedErrors(nameof(TuioSender));
 250
 6251            IsInitialized = false;
 6252        }
 253    }
 254}