一些挖後,我發現來實現對雨燕側流編程(使用本地斯威夫特的能力)的方式。事實證明,Swift中的方式非常類似於Objective C中的方式。
在Swift中啓用流編程所需的兩個函數是func connect()
,我必須自己編寫這兩個函數,而func stream(_ aStream: Stream, handle eventCode: Stream.Event)
一種方法在StreamDelegate
。
這裏是func connect()
樣子:
func connect() {
Stream.getStreamsToHost(withName: <serverIP>, port: <serverPort>, inputStream: &inputStream, outputStream: &)
guard let inputStream = inputStream, let outputStream = outputStream else {
print(" ->\tNetworkControllerError: Cannot open inputstream/outputstream.")
return
}
// Set delegate
inputStream.delegate = self
outputStream.delegate = self
let socketWorkQueue = DispatchQueue(label: "socketWorkQueue", attributes: .concurrent)
CFReadStreamSetDispatchQueue(inputStream, socketWorkQueue)
CFWriteStreamSetDispatchQueue(outputStream, socketWorkQueue)
inputStream.open()
outputStream.open()
}
這裏是什麼func stream(_ aStream: Stream, handle eventCode: Stream.Event)
樣子:
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
if aStream === inputStream {
switch eventCode {
case Stream.Event.errorOccurred:
streamEventQueue.async {
// do something here
}
break
case Stream.Event.openCompleted:
streamEventQueue.async {
// do something here
}
break
case Stream.Event.hasBytesAvailable:
streamEventQueue.async {
// do something here
let output = read()
}
break
case Stream.Event.endEncountered:
streamEventQueue.async {
// do something here
}
break
default:
break
}
}
else if aStream === outputStream {
switch eventCode {
case Stream.Event.errorOccurred:
streamEventQueue.async {
// do something here
}
break
case Stream.Event.openCompleted:
streamEventQueue.async {
// do something here
}
break
default:
break
}
}
}
所以stream()
功能應該是在我的應用程序來進行狀態轉換的唯一的地方由網絡連接/斷開引起。請注意,我還使用串行事件隊列來處理流事件。這是爲了防止可能導致國家腐敗的任何潛在的競爭條件。
對於那些對流編程不太熟悉的人來說,這是一個服務器 - 客戶端通信模式,它保持連接/套接字活着。連接需要保持活躍,主要是由於服務器和客戶端之間存在持續通信。像RESTful API這樣的通信模式會嚴重影響服務器的客戶請求,因此不推薦使用。
您是否計劃每次都建立一個新的連接或保持連接?您是否從NSURLSession中探索了內置的API,以查看它們是否滿足您的需求? – jtbandes
@jtbandes感謝您的及時回覆。我需要爲應用程序保留一個持續的TCP連接。我也研究過NSURLSession,但是看起來這個API更適合HTTP RESTful支持(我非常樂意被糾正)。對我而言,不斷地向服務器發起新的REST調用會給服務器帶來巨大的負擔。 – cafemike