CFStreamCreatePairWithSocketToHost - How to handle the network disconnect?

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