diff options
-rw-r--r-- | Sources/swiftGopherClient/gopherClient.swift | 50 | ||||
-rw-r--r-- | Tests/swiftGopherClientTests/swiftGopherClientTests.swift | 6 |
2 files changed, 56 insertions, 0 deletions
diff --git a/Sources/swiftGopherClient/gopherClient.swift b/Sources/swiftGopherClient/gopherClient.swift index 802d646..68cca6c 100644 --- a/Sources/swiftGopherClient/gopherClient.swift +++ b/Sources/swiftGopherClient/gopherClient.swift @@ -105,6 +105,56 @@ public class GopherClient { #endif } + + @available(iOS 13.0, *) + @available(macOS 10.15, *) + public func sendRequest(to host: String, port: Int = 70, message: String) async throws -> [gopherItem] { + return try await withCheckedThrowingContinuation { continuation in + let bootstrap = self.createBootstrap(message: message) { result in + continuation.resume(with: result) + } + + bootstrap.connect(host: host, port: port).whenComplete { result in + switch result { + case .success(let channel): + channel.closeFuture.whenComplete { _ in + print("Connection Closed") + } + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private func createBootstrap( + message: String, + completion: @escaping (Result<[gopherItem], Error>) -> Void + ) -> NIOClientTCPBootstrapProtocol { + let handler = GopherRequestResponseHandler(message: message, completion: completion) + + #if os(Linux) + return ClientBootstrap(group: eventLoopGroup) + .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) + .channelInitializer { channel in + channel.pipeline.addHandler(handler) + } + #else + if #available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, visionOS 1.0, *) { + return NIOTSConnectionBootstrap(group: group) + .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) + .channelInitializer { channel in + channel.pipeline.addHandler(handler) + } + } else { + return ClientBootstrap(group: group) + .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) + .channelInitializer { channel in + channel.pipeline.addHandler(handler) + } + } + #endif + } /// Shuts down the event loop group, releasing any resources. /// diff --git a/Tests/swiftGopherClientTests/swiftGopherClientTests.swift b/Tests/swiftGopherClientTests/swiftGopherClientTests.swift index dfa46b8..47d0f24 100644 --- a/Tests/swiftGopherClientTests/swiftGopherClientTests.swift +++ b/Tests/swiftGopherClientTests/swiftGopherClientTests.swift @@ -35,4 +35,10 @@ final class GopherClientTests: XCTestCase { wait(for: [expectation], timeout: 30) } + + func testGopherClientAsync() async throws { + let client = GopherClient() + let reply = try await client.sendRequest(to: "gopher.navan.dev", message: "\r\n") + XCTAssertNotNil(reply) + } } |