We have created socket for streaming using the API "CFStreamCreatePairWithSocketToHost".
func openStream() {
if let aUrl = url {
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(
kCFAllocatorDefault,
aUrl as CFString,
port!,
&readStream,
&writeStream)
iStream = readStream!.takeRetainedValue()
oStream = writeStream!.takeRetainedValue()
if ssl == true {
let dict = [
kCFStreamSSLValidatesCertificateChain: kCFBooleanFalse, // allow self-signed certificate
kCFStreamSSLLevel: kCFStreamSSLValidatesCertificateChain // don't understand, why there isn't a constant for version 1.2
] as CFDictionary
let sslSetRead = CFReadStreamSetProperty(iStream, CFStreamPropertyKey(kCFStreamPropertySSLSettings), dict)
let sslSetWrite = CFWriteStreamSetProperty(oStream, CFStreamPropertyKey(kCFStreamPropertySSLSettings), dict)
if sslSetRead == false || sslSetWrite == false {
//print("SSL Configuration Failed")
}
}
commonStr = ""
open(iStream)
open(oStream)
print("Open Stream")
}
}
Used the below delegate for getting events.
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case .endEncountered, .errorOccurred:
streamError()
break
case .hasBytesAvailable:
if let iStream = iStream {
if aStream == iStream {
//read data
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
var len: Int
while iStream.hasBytesAvailable {
len = iStream.read(buffer, maxLength: bufferSize)
if len > 0 {
let output = Data.init(bytes: buffer, count: len)
bufferTokenize(output: output)
}else {
break
}
}
buffer.deallocate()
}
}
break
case .hasSpaceAvailable:
if aStream == oStream! {
streamReady()
}
break
case .openCompleted:
if aStream == oStream! {
if let del = delegate {
del.connectionCompleted()
}
}
break
default:
break
}
}
Other Supporting functions are
func streamError() {
stopStream()
NSObject.cancelPreviousPerformRequests(withTarget:self)
perform(#selector(callReconnect), with: nil, afterDelay: 2)
}
func open(_ stream: Stream?) {
if let aStream = stream {
aStream.delegate = self
aStream.schedule(in: RunLoop.main, forMode: .common)
aStream.open()
}
}
func stopStream() {
print("Stop Stream")
close(iStream)
close(oStream)
}
func close(_ stream: Stream?) {
if nil != stream {
stream?.close()
stream?.remove(from: RunLoop.main, forMode: .common)
}
}
func resetStream() {
stopStream()
openStream()
}
It is working fine for below steps
1. Create connection - Open stream
2. get "openCompleted" event - then Create request
3. get "hasSpaceAvailable" event - then Send Request
4. get "hasBytesAvailable" event - then Handle Data
5. Disconnect connection from server for testing purpose
6. get "endEncountered" event - then Close the connection and Recreate the connection from step 1
But the below scenario not working properly
Follow the steps 1 - 4 then
5. Disconnect Internet connection for testing purpose - the event "hasBytesAvailable" stopped
6. Again reconnect the Internet connection within 30 seconds - now we get "hasBytesAvailable" event
But the reconnect time extent to 5 minute - We don't have any event, and don't get "endEncountered" or "errorOccurred" also. Then how to move to next stop.
Please Help, Thanks
Regards,
Elamvazhuthi K