SwiftAsyncSocket 0.2.0

SwiftAsyncSocket 0.2.0

chouheiwa 维护。



  • 作者:
  • chouheiwa

SwiftAsyncSocket

Version Status Platform Carthage compatible GitHub license

SwiftAsyncSocket 是一个基于 GCD 的 socket 连接工具,采用 Swift 完全实现。

我将它从 CocoaAsyncSocket 翻译而来。

换句话说,如果您使用过 CocoaAsyncSocket,您会对这个感到熟悉。

SwiftAsyncSocket 支持TCP/IP 和 UDP/IP socket。

SwiftAsyncSocket 比起 CocoaAsyncSocket 更重。因为 CocoaAsyncSocket 单个文件中就有超过 8,000 行代码。我在多个文件中分散了这些逻辑。

SwiftAsyncSocket 已通过 SwiftLint 检查。

安装

1. 手动安装

SwiftAsyncSocket 现在支持 Cocoapods

因此,您只能通过以下步骤使用它。

# Download the source of the code 
git clone https://github.com/chouheiwa/SwiftAsnycSocket.git

cd SwiftAsnycSocket

open ./SwiftAsyncSocket.xcodeproj

然后打开 xcodeproj 文件,在 Xcode 中使用 cmd + b 编译框架,最后将其复制到您的项目中。

2. CocoaPods

通过将以下行添加到您的 Podfile 中来使用 CocoaPods 进行安装:

use_frameworks! # Add this if you are targeting iOS 8+ or using Swift
pod 'SwiftAsyncSocket'  

3. Carthage

SwiftAsyncSocket 兼容 Carthage。要包含它,请将以下行添加到您的 Cartfile

github "chouheiwa/SwiftAsyncSocket"

使用方法

TCP/IP

1. 以客户端方式使用。

如果socket服务器已启动在 localhost:8080

import SwiftAsyncSocket

class Client {
    var socket: SwiftAsyncSocket
    
    init() {
        // you can not set delegate here because in this line that init function has not complete.So set delegate next line
        socket = SwiftAsyncSocket(delegate: nil, delegateQueue: DispatchQueue.global(), socketQueue: nil)
        // All the delagate function is optional. If you want to use. You can implement it.
        socket.delgate = self
        
        do {
            // Connected 
            try socket.connect(toHost: "localhost", onPort: 8080)
        } catch {
            // Here to print error
            print("\(error)")
        }
    }
}
/// If you want to use as client, 
/// at least you need to implement these three method
extension Client: SwiftAsyncSocketDelgate {
    func socket(_ socket: SwiftAsyncSocket, didConnect toHost: String, port: UInt16) {
        // If you use socket.connect(toHost: , onPort: )
        // When the socket connected, this method will be called
        // Then you can call 
        // socket.write(data:, timeOut:, tag:) 
        // to send the data to server or 
        // socket.readData(timeOut:, tag:)
        // to read data from server
        
    }
    
    func socket(_ socket: SwiftAsyncSocket, didWriteDataWith tag: Int) {
        // When send data complete, this method will be called
    }

    func socket(_ socket: SwiftAsyncSocket, didRead data: Data, with tag: Int) {
        // When read data complete, this method will return the data from server
    }
}
2. 以服务器方式使用。
import Foundation
import SwiftAsyncSocket
class Server: SwiftAsyncSocketDelegate {
    var baseSocket: SwiftAsyncSocket
    /// Here we use map to help we locate which socket has already been disconnected
    var acceptSockets: [String:SwiftAsyncSocket] = [:]

    var port: UInt16

    var canAccept: Bool = false

    var canSendData: ((SwiftAsyncSocket) -> Void)?

    var didReadData: ((Data) -> Void)?

    init() {
        baseSocket = SwiftAsyncSocket(delegate: nil, delegateQueue: DispatchQueue.global(), socketQueue: nil)

        port = UInt16.random(in: 1024..<50000)

        baseSocket.delegate = self

        do {
            canAccept = try baseSocket.accept(port: port)

            canAccept = true
        } catch let error as SwiftAsyncSocketError {
            print("\(error)")
        } catch {
            fatalError("\(error)")
        }
    }

    func socket(_ socket: SwiftAsyncSocket, didAccept newSocket: SwiftAsyncSocket) {
        /// We use a time and a random number to make key unique
        let random = Int.random(in: 0..<99999)

        let date = Date()
        let key = "\(date)\(random)"
        acceptSockets[key] = newSocket
        newSocket.userData = key
        newSocket.delegate = self
        newSocket.delegateQueue = DispatchQueue.global()
        canSendData?(newSocket)
    }

    func socket(_ socket: SwiftAsyncSocket, didWriteDataWith tag: Int) {

    }

    func socket(_ socket: SwiftAsyncSocket, didRead data: Data, with tag: Int) {
        didReadData?(data)
    }

    func socket(_ socket: SwiftAsyncSocket?, didDisconnectWith error: SwiftAsyncSocketError?) {
        guard let key = socket?.userData as? String else { return }

        acceptSockets.removeValue(forKey: key)
    }
}

UDP

1. 以客户端方式使用。
import Foundation
import SwiftAsyncSocket

class UdpClient {
    var socket: SwiftAsyncUDPSocket
    
    init() {
        // you can not set delegate here because in this line that init function has not complete.So set delegate next line
        serverSocket = SwiftAsyncUDPSocket(delegate: nil, delegateQueue: DispatchQueue.main)
        // All the delagate function is optional. If you want to use. You can implement it.
        socket.delgate = self
        
        do {
            // Connected 
            try socket.connect(toHost: "localhost", onPort: 8090)
        } catch {
            // Here to print error
            print("\(error)")
        }
    }
    
    func sendData() {
        let data = "data".data(using: .utf8) ?? Data()
        
        do {
            socket.send(data: data, timeout: -1, tag: 10)
            // Use next line if you want to receive data
            try socket.receiveAlways()
        } catch {
            print("\(error)")
        }
    }
}
/// You don't need implement any method to send data
extension Client: SwiftAsyncUDPSocketDelgate {
    func updSocket(_ socket: SwiftAsyncUDPSocket,
                   didReceive data: Data,
                   from address: SwiftAsyncUDPSocketAddress,
                   withFilterContext filterContext: Any?) {
                   
    }
}
2. 用作服务器。
import Foundation
import SwiftAsyncSocket

class UdpServer {
    let port: UInt16
    let serverSocket: SwiftAsyncUDPSocket

    var didReceiveData: ((Data) -> Void)?

    init(port: UInt16) throws {
        self.port = port
        serverSocket = SwiftAsyncUDPSocket(delegate: nil, delegateQueue: DispatchQueue.main)

        serverSocket.delegate = self

        try serverSocket.bind(port: port)

        try serverSocket.receiveAlways()
    }
}
extension UdpServer: SwiftAsyncUDPSocketDelegate {
    func updSocket(_ socket: SwiftAsyncUDPSocket,
                   didReceive data: Data,
                   from address: SwiftAsyncUDPSocketAddress,
                   withFilterContext filterContext: Any?) {
                   
        let string = String(data: data, encoding: .utf8) ?? ""
        print("Receive Data: \(string)")
    }
}