I would like to use NWProtocolQUIC in Swift's Network.framework to prepare multiple QUIC Streams and send different data to the server for each.
class QuicConnection {
var acceptConnection: NWConnection?
var openConnection: NWConnection?
var acceptConnectionState: NWConnection.State?
var openConnectionState: NWConnection.State?
var receiveFromAcceptConnection: String?
static func makeNWParameters() -> NWParameters {
let options = NWProtocolQUIC.Options(alpn: ["echo"])
options.direction = .bidirectional
let securityProtocolOptions: sec_protocol_options_t = options.securityProtocolOptions
sec_protocol_options_set_verify_block(securityProtocolOptions,
{ (_: sec_protocol_metadata_t,
_: sec_trust_t,
complete: @escaping sec_protocol_verify_complete_t) in
complete(true)
}, DispatchQueue.main)
return NWParameters(quic: options)
}
let group: NWConnectionGroup
init() {
print("init")
let parameters = Self.makeNWParameters()
let descriptor = NWMultiplexGroup(to: .hostPort(host: "192.168.0.20", port: 4242))
group = NWConnectionGroup(with: descriptor, using: parameters)
//subscribe()
group.stateUpdateHandler = { (state: NWConnectionGroup.State) in
print("state: \(state)")
switch state {
case .ready:
print("quic connected!")
default:
break
}
}
group.newConnectionHandler = { [weak self] (connection: NWConnection) in
print("new connection: \(connection)")
self?.acceptConnection = connection
self?.acceptConnection?.stateUpdateHandler = { [weak self] (state: NWConnection.State) in
self?.acceptConnectionState = state
}
self?.subscribeAcceptConnection()
self?.acceptConnection?.start(queue: DispatchQueue.main)
}
group.start(queue: DispatchQueue.main)
}
func createStream() {
//guard let group else { return }
let options = NWProtocolQUIC.Options()
options.direction = .bidirectional
let securityProtocolOptions: sec_protocol_options_t = options.securityProtocolOptions
sec_protocol_options_set_verify_block(securityProtocolOptions,
{ (_: sec_protocol_metadata_t,
_: sec_trust_t,
complete: @escaping sec_protocol_verify_complete_t) in
complete(true) // Insecure !!!
}, DispatchQueue.main)
openConnection = NWConnection(from: group)
openConnectionState = openConnection?.state
openConnection?.stateUpdateHandler = { [weak self] (state: NWConnection.State) in
self?.openConnectionState = state
print("state: \(state)")
switch state {
case .ready:
print("stream connected!")
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self?.send(message: "marker1")
}
default:
break
}
}
openConnection?.start(queue: DispatchQueue.main)
}
func send(message: String) {
print("send start")
let completion: NWConnection.SendCompletion = .contentProcessed { (error: Error?) in
if let error = error {
print("send error: \(error)")
} else {
print("send successful")
}
}
openConnection?.send(content: message.data(using: .utf8)!,
contentContext: .defaultMessage,
isComplete: true,
completion: completion)
print("message: \(message)")
}
}
When the app starts, it calls the init function of this QuicConnection class to create an instance and build the QUIC tunnel." quic connected" log appears, and when a specific action is performed in the app, the createStream function is called to put up a stream." stream connected" log is displayed, but when I then try to send data using the send function, the "send successful" message is displayed, but there is no output on the server side indicating that the message was received from the client. However, when I try to send data using the send function after that, I get a "send successful" message.
I don't think there is a problem on the server side, because I can communicate well when only NWConnection is used without NQConnectionGroup. The server is using quic-go.
I would like to borrow knowledge from those who have handled QUIC streams in Swift.
Below are Apple's announcement and official documents that I referred to. I wrote the code referring to these, but even though I can connect the QUIC tunnels, I can not send data by setting up individual streams.
https://developer.apple.com/videos/play/wwdc2021/10094/
https://developer.apple.com/documentation/network/nwprotocolquic