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)); } }
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; }
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); } }