manager管家 ?--- 交給client處理 ?其實(shí)還是服務(wù)器在處理---client中block回調(diào)還是讓服務(wù)器處理而已
服務(wù)器
1> 創(chuàng)建Socket
2> 綁定端口
3> 監(jiān)聽listen
4> 接受客戶端的鏈接(accept) socket
* 阻塞式的函數(shù)
*/
如果離開房間?
client.callback = {[unowned self] (isLeave, data, client) in
// 1.是否需要移動客戶端
if isLeave {
if let index = self.clients.index(of: client) {
self.clients.remove(at: index)
client.tcpClient.close()
}
}
// 2.將消息轉(zhuǎn)發(fā)出去
for c in self.clients {
c.tcpClient.send(data: data)
}
如果沒有正在運(yùn)行 也移除
client.removeClientCallback = {[unowned self] (client) in
if let index = self.clients.index(of: client) {
self.clients.remove(at: index)
client.tcpClient.close()
}
}
+++++++++++++++++++++++++++++++++++++++++++++++++++
import Cocoa
class IMServerManager: NSObject {
fileprivate lazy var tcpServer : TCPServer = TCPServer(addr: "0.0.0.0", port: 2828)
fileprivate lazy var clients : [IMClient] = [IMClient]()
}
extension IMServerManager {
func startRunning() {
// 1.監(jiān)聽客戶端的鏈接
tcpServer.listen()
// 2.接受客戶端的鏈接
DispatchQueue.global().async {
while true {
if let tcpClient = self.tcpServer.accept() {
DispatchQueue.global().async {
self.handleClient(tcpClient)
}
}
}
}
}
func stopRunning() {
}
}
extension IMServerManager {
fileprivate func handleClient(_ client : TCPClient) {
let client = IMClient(client: client)
clients.append(client)
client.callback = {[unowned self] (isLeave, data, client) in
// 1.是否需要移動客戶端
if isLeave {
if let index = self.clients.index(of: client) {
self.clients.remove(at: index)
client.tcpClient.close()
}
}
// 2.將消息轉(zhuǎn)發(fā)出去
for c in self.clients {
c.tcpClient.send(data: data)
}
}
client.removeClientCallback = {[unowned self] (client) in
if let index = self.clients.index(of: client) {
self.clients.remove(at: index)
client.tcpClient.close()
}
}
client.startReadMessage()
}
}
+++++++++++
import Cocoa
class IMClient: NSObject {
var tcpClient : TCPClient
var callback : ((Bool, Data, IMClient) -> Void)?
var removeClientCallback : ((IMClient) -> Void)?
fileprivate var isRunning : Bool = false
init(client : TCPClient) {
self.tcpClient = client
}
}
extension IMClient {
func startReadMessage() {
isRunning = true
while isRunning {
if let lengthByte = tcpClient.read(4) {
// 1.獲取數(shù)據(jù)的長度
let lengthData = NSData(bytes: lengthByte, length: 4)
var length : Int = 0
lengthData.getBytes(&length, length: 4)
// 2.讀取消息的類型
guard let typeBytes = tcpClient.read(2) else {
tcpClient.read(length)
continue
}
let typeData = NSData(bytes: typeBytes, length: 2)
var type : Int = 0
typeData.getBytes(&type, length: 2)
print(type)
// 3.獲取具體的內(nèi)容
guard let dataBytes = tcpClient.read(length) else {
return
}
let msgData = Data(bytes: dataBytes, count: length)
// 1> 判斷是否是離開消息: 告訴其他人, 有人離開房間, 將該客戶端從數(shù)組中移除
// 2> 其他消息, 直接轉(zhuǎn)發(fā)給其他客戶端
let isLeave = type == 1 ? true : false
callback?(isLeave, (lengthData as Data) + (typeData as Data) + msgData, self)
} else {
isRunning = false
removeClientCallback?(self)
}
}