웹소켓을 이용하면 웹브라우저와 서버간의 양방향 실시간 통신이 가능하다.
자세한건 해당 글을 참고하자!
웹소켓
var websocketTask: URLSessionWebSocketTask?
private func connect(with url: URL) {
// 연결상태였을 수 있으니 먼저 disConnect() 후 재연결
disConnect()
// URLSession의 delegate를 self로 설정
let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
// 변수 webSocketTask에 설정
// session.webSocketTask(with: url)를 호출하여 주어진 URL로 WebSocket 작업 생성
websocketTask = session.webSocketTask(with: url)
websocketTask?.resume()
receiveMessage()
}
private func disConnect() {
// URLSessionWebSocketTask의 cancel() 메소드로 연결 해제
websocketTask?.cancel(with: .goingAway, reason: nil)
}
private func sendMessage() {
// 서버에 전송할 JSON 형식의 문자열을 생성
let jsonString = #"{"op":"price_sub"}"#
// 문자열 메시지를 생성
let messageToSend = URLSessionWebSocketTask.Message.string(jsonString)
// 생성한 메시지를 WebSocket 서버로 전송
websocketTask?.send(messageToSend) { error in
if error != nil {
print(error!)
} else {
self.receiveMessage()
}
}
}
private func receiveMessage() {
// WebSocket을 통해 서버로부터 메시지를 비동기적으로 수신
websocketTask?.receive { result in
// 성공 케이스와 실패 케이스 각각 처리
switch result {
case .success(.string(let msg)):
self.handleMessage(msg)
self.receiveMessage()
case .success(.data(let msg)):
if let stringMsg = String(data: msg, encoding: .utf8) {
self.handleMessage(stringMsg)
}
self.receiveMessage()
case .success(_):
print("Received unknown message type")
case .failure(let error):
print(error.localizedDescription)
}
}
}
// 받은 데이터 디코딩
private func handleMessage(_ message: String) {
do {
let decoder = JSONDecoder()
let result = try decoder.decode(SocketResponse.self, from: Data(message.utf8))
DispatchQueue.main.async {
self.dogePriceLabel.text = result.x.value
}
} catch {
print("Error decoding message:", error.localizedDescription)
}
}
URLSessionWebSocketDelegate
프로토콜 구현extension ViewController: URLSessionWebSocketDelegate {
func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol: String?) {
print("연결됨 \(session), webSocketTask: \(webSocketTask), didOpenWithProtocol: \(String(describing: didOpenWithProtocol)))")
}
func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith: URLSessionWebSocketTask.CloseCode, reason: Data?) {
print("끊김 \(session), closeCode: \(didCloseWith), reason: \(String(describing: reason))")
}
}