private void ProcessNamedConnectionRequest(StandardNamedConnectRqPacket packet) { StandardNamedConnectRsPacket response = new StandardNamedConnectRsPacket {ConnectionId = packet.ConnectionId}; // By default the conn id going back is the conn id of the request // this will change if the connection is a success, then it will be our conn id. lock (_receiveConnectLock) { // If this connection exists if (_tcpConnections.IsRemoteConnection(packet.ConnectionId)) { Logger.Debug("Request for connection id [" + packet.ConnectionId + "] already established, resending response"); TcpConnectionHolder tcpConnectionHolder = _tcpConnections.GetRemoteConnection(packet.ConnectionId); response.RemoteConnectionId = tcpConnectionHolder.Connection.ConnectionId; response.ProtocolId = tcpConnectionHolder.Connection.ProtocolId; response.Sequence = tcpConnectionHolder.Connection.NextSeqToSend; // we can respond that we are already established here response.Success = true; } else { lock (_listeningNamedTCPEndPoints) { if (_listeningNamedTCPEndPoints.ContainsKey(packet.ConnectionName)) { byte localConnectionId = GetNextConnectionId(); Logger.Debug("Found a listener for " + packet.ConnectionName + " connecting local conn [" + localConnectionId + "] to remote conn [" + packet.ConnectionId + "]"); byte agreedProtocolId = packet.ProtocolId; if (packet.ProtocolId > MaxSupportedProtocolId) { Logger.Debug("They wanted protocol " + packet.ProtocolId + ", but I only support up to " + MaxSupportedProtocolId + ", so I propose it."); agreedProtocolId = MaxSupportedProtocolId; } Logger.Debug("I have agreed to protocol " + agreedProtocolId); response.ProtocolId = agreedProtocolId; response.Sequence = (ushort) (_rand.Next(ushort.MaxValue)); ITcpTransportLayer connection = null; switch (agreedProtocolId) { case (2): { connection = new TcpTransportLayerSlidingWindow(this, localConnectionId, packet.ConnectionId, response.Sequence, packet.Sequence); break; } default: { Logger.Error("Failed to agree on a tcp protocol, I don't support " + agreedProtocolId); break; } } if (connection != null) { // only add the connection if response.Success = _listeningNamedTCPEndPoints[packet.ConnectionName].ConnectCallback(connection.Socket); if (response.Success) { // set it up to tie up loose ends when the connection dies connection.ConnectionClose += ConnectionOnConnectionClose; _tcpConnections.Add(connection); response.RemoteConnectionId = localConnectionId; } } else { response.Success = false; } } else { Logger.Warn("No listener for " + packet.ConnectionName); response.Success = false; } } } } Logger.Debug("Sending connection response : " + response); SendData(response); if (response.Success) { // This sends a positive response, we would like to get an Ack of this connection response // which will open this connection, but should that ack not arrive, let set a timer to automatically // open this connection after 10 seconds // we know that the sender will retry the connection should it not receive our response. _tcpConnections.GetLocalOpenConnection(response.RemoteConnectionId).StartTimerToOpen(); } }
public ITcpTransportLayer ConnectNamed(byte connectionId, String namedEndPoint, int timeout, byte protocolId) { long waitTime = timeout; Logger.Debug("Connecting to " + namedEndPoint + ", timeout is " + waitTime + "ms"); StandardNamedConnectRqPacket packet = new StandardNamedConnectRqPacket(connectionId) { ConnectionName = namedEndPoint, ProtocolId = protocolId, Sequence = (ushort)(_rand.Next(ushort.MaxValue)) }; long startTime = DateTime.Now.Ticks; _connectEvents.Add(connectionId, new AutoResetEvent(false)); do { _transport.SendData(packet); packet.ResendCount++; var timeSpan = new TimeSpan(DateTime.Now.Ticks - startTime); if (timeSpan.TotalMilliseconds > waitTime) { Logger.Debug("Connect timeout : " + timeSpan.TotalMilliseconds + "ms"); if (_connectEvents.ContainsKey(connectionId)) { _connectEvents.Remove(connectionId); } throw new TimeoutException("Timeout occured while connecting to " + namedEndPoint); } Logger.Debug("Waiting for connect response from " + namedEndPoint); } while (_connectEvents.ContainsKey(connectionId) && !_connectEvents[connectionId].WaitOne(5000)); try { var response = _connectResults[connectionId]; if (response.Success) { ITcpTransportLayer connection; switch (response.ProtocolId) { case (2): { connection = new TcpTransportLayerSlidingWindow(_transport, connectionId, response.RemoteConnectionId, packet.Sequence, response.Sequence); break; } default: { throw new ConnectionException("Failed to agree on a protocol, I don't support " + response.RemoteConnectionId); } } Logger.Debug("We have agreed to protocol " + response.ProtocolId); return(connection); } throw new ConnectionException("Failed to connect to " + namedEndPoint + ", service is unavailable"); } finally { _connectResults.Remove(connectionId); } }
private void ProcessNamedConnectionRequest(StandardNamedConnectRqPacket packet) { StandardNamedConnectRsPacket response = new StandardNamedConnectRsPacket { ConnectionId = packet.ConnectionId }; // By default the conn id going back is the conn id of the request // this will change if the connection is a success, then it will be our conn id. lock (_receiveConnectLock) { // If this connection exists if (_tcpConnections.IsRemoteConnection(packet.ConnectionId)) { Logger.Debug("Request for connection id [" + packet.ConnectionId + "] already established, resending response"); TcpConnectionHolder tcpConnectionHolder = _tcpConnections.GetRemoteConnection(packet.ConnectionId); response.RemoteConnectionId = tcpConnectionHolder.Connection.ConnectionId; response.ProtocolId = tcpConnectionHolder.Connection.ProtocolId; response.Sequence = tcpConnectionHolder.Connection.NextSeqToSend; // we can respond that we are already established here response.Success = true; } else { lock (_listeningNamedTCPEndPoints) { if (_listeningNamedTCPEndPoints.ContainsKey(packet.ConnectionName)) { byte localConnectionId = GetNextConnectionId(); Logger.Debug("Found a listener for " + packet.ConnectionName + " connecting local conn [" + localConnectionId + "] to remote conn [" + packet.ConnectionId + "]"); byte agreedProtocolId = packet.ProtocolId; if (packet.ProtocolId > MaxSupportedProtocolId) { Logger.Debug("They wanted protocol " + packet.ProtocolId + ", but I only support up to " + MaxSupportedProtocolId + ", so I propose it."); agreedProtocolId = MaxSupportedProtocolId; } Logger.Debug("I have agreed to protocol " + agreedProtocolId); response.ProtocolId = agreedProtocolId; response.Sequence = (ushort)(_rand.Next(ushort.MaxValue)); ITcpTransportLayer connection = null; switch (agreedProtocolId) { case (2): { connection = new TcpTransportLayerSlidingWindow(this, localConnectionId, packet.ConnectionId, response.Sequence, packet.Sequence); break; } default: { Logger.Error("Failed to agree on a tcp protocol, I don't support " + agreedProtocolId); break; } } if (connection != null) { // only add the connection if response.Success = _listeningNamedTCPEndPoints[packet.ConnectionName].ConnectCallback(connection.Socket); if (response.Success) { // set it up to tie up loose ends when the connection dies connection.ConnectionClose += ConnectionOnConnectionClose; _tcpConnections.Add(connection); response.RemoteConnectionId = localConnectionId; } } else { response.Success = false; } } else { Logger.Warn("No listener for " + packet.ConnectionName); response.Success = false; } } } } Logger.Debug("Sending connection response : " + response); SendData(response); if (response.Success) { // This sends a positive response, we would like to get an Ack of this connection response // which will open this connection, but should that ack not arrive, let set a timer to automatically // open this connection after 10 seconds // we know that the sender will retry the connection should it not receive our response. _tcpConnections.GetLocalOpenConnection(response.RemoteConnectionId).StartTimerToOpen(); } }