vapor-community / sockets

🔌 Non-blocking TCP socket layer, with event-driven server and client.
MIT License
575 stars 54 forks source link

TCP client send timeout #113

Closed danshevluk closed 6 years ago

danshevluk commented 7 years ago

I'm trying to use socks for my network layer in iOS application and method client.socket.setSendingTimeout(_:) appears to be broken. Client reading forever if network is unreachable. Timeout works well for receive, but not for read. I looked at tests and noticed that they don't cover this case at all: https://github.com/vapor/socks/blob/master/Tests/SocksCoreTests/TimeoutTests.swift#L82

danshevluk commented 7 years ago

My current solution (⚠️ it's really bad 🚧):

let timeout: DispatchTimeInterval = .seconds(4)
let sendWork = DispatchWorkItem { 
  guard let client = self.client else { return }

  do {
    try client.send(bytes: bytes)
    // send success to callback
  } catch let error {
    // send error to callback
  }
}

writingQueue.async(execute: sendWork)
DispatchQueue.global(qos: .background).asyncAfter(deadline: DispatchTime.now() + timeout) { 
  guard !sendWork.isCancelled else { return }
  work.cancel()
  DispatchQueue.main.async { 
    // send time out error to callback
  }
}
tanner0101 commented 7 years ago
    public func setReceivingTimeout(_ newValue:timeval) throws {
        if isClosed { throw SocketsError(.socketIsClosed) }
        try descriptor.setOption(level: SOL_SOCKET, name: SO_RCVTIMEO, value: newValue)
    }

    public func setSendingTimeout(_ newValue: timeval) throws {
        if isClosed { throw SocketsError(.socketIsClosed) }
        try descriptor.setOption(level: SOL_SOCKET, name: SO_SNDTIMEO, value: newValue)
    }

That's strange to hear as the implementations for both send/recv have identical implementations. I have no idea what this could be.