iOS - WebSocket 양방향 통신

이한솔·2024년 6월 21일
0

iOS 앱개발 🍏

목록 보기
42/49

WebSocket 양방향 통신

웹소켓을 이용하면 웹브라우저와 서버간의 양방향 실시간 통신이 가능하다.
자세한건 해당 글을 참고하자!
웹소켓



WebSocket 구현

  1. 소켓 연결
    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()
    }
  1. 소켓 연결 해제
   private func disConnect() {
        // URLSessionWebSocketTask의 cancel() 메소드로 연결 해제
        websocketTask?.cancel(with: .goingAway, reason: nil)
    }
  1. 메세지 보내기
   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()
            }
            
        }
    }
  1. 메세지 받기
   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)
        }
    }
  1. 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))")
    }
    
}

0개의 댓글