SwiftAsyncSocket
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)")
}
}