/// <exception cref="System.IO.IOException"></exception>
public ClientConnection(ClientConnectionManager clientConnectionManager,
ClientInvocationService invocationService,
int id,
Address address,
ClientNetworkConfig clientNetworkConfig)
{
_clientConnectionManager = clientConnectionManager;
_id = id;
var isa = address.GetInetSocketAddress();
var socketOptions = clientNetworkConfig.GetSocketOptions();
var socketFactory = socketOptions.GetSocketFactory() ?? new DefaultSocketFactory();
_clientSocket = socketFactory.CreateSocket();
try
{
_clientSocket = new Socket(isa.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var lingerOption = new LingerOption(true, 5);
if (socketOptions.GetLingerSeconds() > 0)
{
lingerOption.LingerTime = socketOptions.GetLingerSeconds();
}
_clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerOption);
_clientSocket.NoDelay = socketOptions.IsTcpNoDelay();
_clientSocket.ReceiveTimeout = socketOptions.GetTimeout() > 0 ? socketOptions.GetTimeout() : -1;
var bufferSize = socketOptions.GetBufferSize() * 1024;
if (bufferSize < 0)
{
bufferSize = BufferSize;
}
_clientSocket.SendBufferSize = bufferSize;
_clientSocket.ReceiveBufferSize = bufferSize;
var connectionTimeout = clientNetworkConfig.GetConnectionTimeout() > -1
? clientNetworkConfig.GetConnectionTimeout()
: ConnectionTimeout;
var socketResult = _clientSocket.BeginConnect(address.GetHost(), address.GetPort(), null, null);
if (!socketResult.AsyncWaitHandle.WaitOne(connectionTimeout, true) || !_clientSocket.Connected)
{
// NOTE, MUST CLOSE THE SOCKET
_clientSocket.Close();
throw new IOException("Failed to connect to " + address);
}
_sendBuffer = ByteBuffer.Allocate(BufferSize);
_receiveBuffer = ByteBuffer.Allocate(BufferSize);
_builder = new ClientMessageBuilder(invocationService.HandleClientMessage);
var networkStream = new NetworkStream(_clientSocket, false);
if (clientNetworkConfig.GetSSLConfig().IsEnabled())
{
var sslStream = new SslStream(networkStream, false,
(sender, certificate, chain, sslPolicyErrors) =>
RemoteCertificateValidationCallback(sender, certificate, chain, sslPolicyErrors,
clientNetworkConfig), null);
var certificateName = clientNetworkConfig.GetSSLConfig().GetCertificateName() ?? "";
sslStream.AuthenticateAsClient(certificateName);
_stream = sslStream;
}
else
{
_stream = networkStream;
}
_live = new AtomicBoolean(true);
}
catch (Exception e)
{
_clientSocket.Close();
if (_stream != null)
{
_stream.Close();
}
throw new IOException("Cannot connect! Socket error:" + e.Message);
}
}