public void ReleaseSocket(ProdysSocket socket)
        {
            if (socket == null)
            {
                return;
            }

            if (!socket.Connected)
            {
                return;
            }

            log.Debug($"IkusNet Returning socket for {socket.IpAddress} to pool. (Socket #{socket.GetHashCode()})");
            var dictionaryForIpAddress = _dictionary.GetOrAdd(socket.IpAddress, s => new ConcurrentBag <ProdysSocket>());

            socket.RefreshEvictionTime();
            dictionaryForIpAddress.Add(socket);
        }
        public async Task <ProdysSocketProxy> TakeSocket(string ipAddress)
        {
            using (new TimeMeasurer("IkusNet Taking socket"))
            {
                var dictionaryForIpAddress = _dictionary.GetOrAdd(ipAddress, s =>
                {
                    log.Info($"IkusNet Creating new Bag for connections to {ipAddress}");
                    return(new ConcurrentBag <ProdysSocket>());
                });

                if (dictionaryForIpAddress.TryTake(out var socket))
                {
                    log.Debug($"IkusNet Reusing existing socket for IP {ipAddress} found in pool. (Socket #{socket.GetHashCode()})");
                    return(new ProdysSocketProxy(socket, this));
                }

                socket = await ProdysSocket.GetConnectedSocketAsync(ipAddress);

                log.Info($"IkusNet New socket to IP {ipAddress} created. (Socket #{socket.GetHashCode()})");
                return(new ProdysSocketProxy(socket, this));
            }
        }
Example #3
0
        public static async Task <ProdysSocket> GetConnectedSocketAsync(string address, int sendTimeout = 300)
        {
            using (new TimeMeasurer("ProdysSocket.GetConnectedSocketAsync"))
            {
                IPAddress ipAddress = GetIpAddress(address);

                if (ipAddress == null)
                {
                    log.Warn($"Unable to resolve ip address for {address}");
                    throw new UnableToResolveAddressException();
                }

                // Try with authenticated connect first
                // INFO: It seems that authenticated connect works also when authentication is not active on the codec. At least on some firmware versions...

                // TODO: Reuse connection if authenticated connect failes.

                ProdysSocket connectedSocket = await ConnectAsync(ipAddress, new CsConnect2(), sendTimeout);

                if (connectedSocket != null)
                {
                    return(connectedSocket);
                }

                log.Warn("Unable to connect to codec at {0} using authenticated connect.", ipAddress);

                // Otherwise, try non authenticated connect
                connectedSocket = await ConnectAsync(ipAddress, new CsConnect(), sendTimeout);

                if (connectedSocket != null)
                {
                    return(connectedSocket);
                }

                log.Warn("Unable to connect to codec at {0}. Both authenticated and unauthenticated connect failed.", ipAddress);
                throw new UnableToConnectException();
            }
        }
 public ProdysSocketProxy(ProdysSocket socket, ProdysSocketPool prodysSocketPool)
 {
     _socket           = socket;
     _prodysSocketPool = prodysSocketPool;
 }
Example #5
0
        private static async Task <ProdysSocket> ConnectAsync(IPAddress ipAddress, ConnectCommandBase connectCmd, int sendTimeout)
        {
            ProdysSocket socket = null;

            try
            {
                socket = new ProdysSocket(ipAddress);

                if (sendTimeout > 0)
                {
                    socket.SendTimeout = sendTimeout;
                }

                var endpoint = new IPEndPoint(ipAddress, Sdk.IkusNet.ExternalProtocolIpCommandsPort);

                await socket.ConnectAsync(endpoint, 4000); // TODO: Added a timeout here, verify that it's ok

                if (!socket.Connected)
                {
                    socket.Close();
                    return(null);
                }

                var sendBytes = connectCmd.GetBytes();
                var sent      = socket.Send(sendBytes);

                if (sent <= 0 || !socket.Connected)
                {
                    socket.Close();
                    return(null);
                }

                // Read response
                var buffer = new byte[16];
                socket.Receive(buffer);

                var command         = (Command)ConvertHelper.DecodeUInt(buffer, 0);
                var length          = (int)ConvertHelper.DecodeUInt(buffer, 4);
                var receivedCommand = (Command)ConvertHelper.DecodeUInt(buffer, 8);
                // TODO: Verify command, length, receivedCommand
                var acknowledged = Convert.ToBoolean(ConvertHelper.DecodeUInt(buffer, 12));

                log.Debug("Connect response from codec at {0}: {1}", ipAddress, acknowledged);

                if (!acknowledged)
                {
                    socket.Close();
                    socket.Dispose();
                    return(null);
                }

                return(socket);
            }
            catch (Exception ex)
            {
                log.Warn(ex, $"Exception when connecting to codec at {ipAddress}, {ex.GetType().FullName}");
                log.Debug(ex, "Exception when using Prodys socket");
                socket?.Close();
                return(null);
            }
        }