apple/RxSwift, ReactorKit

iOS RxStarScream 총정리

lgvv 2022. 1. 12. 14:22

iOS RxStarScream 총정리

 

iOS 개발에서 Socket 통신을 위해서 Starscream을 사용하고 있음.

Starsream을 RxSwift에서 편하게 사용할 수 있게 만들어주는 오픈소스 라이브러리.

 

Starscream을 사이드프로젝트 및 회사에서 사용하는데, 인턴 작업에서 이를 도입하기로 해서 리드해서 작업하기로 함.

Starscream 자체를 RxSwift로 Proxy를 활용해 감싸서 사용할 수도 있지만, 오픈소스부터 분석해서 추후에 기여도 가능한 방향으로 설계하고자 분석

 

 

 

연관포스팅

 

오픈소스 링크

오픈소스가 현재 RxSwift 6점대이지만, 수정한 PR을 요청해도 받아주지 않아서 관리가 되고 있지 않음.

 

https://github.com/RxSwiftCommunity/RxStarscream

 

 

사전준비

우선 웹소켓을 사용할 수 있는 서버가 존재해야 함.

  • 따로 준비할 수 있는 방법이 있는지는 모르겠으나, 사이드에서 이미 사용하고 있어서 이를 활용.

 

코드 샘플

내부 구현보다는 사용법에 초점을 맞춤

  • 웹소켓을 사용하면 소켓작업을 수행할 수 있음
import Then
import SnapKit
import RxCocoa
import RxSwift
import Foundation
import RxStarscream

final class ViewController: UIViewController {
    
    private var disposeBag: DisposeBag
    /// 소켓
    private var socket: WebSocket

    private func bind() {
    
        // 2. 버튼 클릭스 웹소켓을 통해 데이터 전송
        loadButton.rx.tap
            .bind(with: self) { this in
                // 서버에 요청할 임시 요청 데이터
                let message = "{\n\"type\": \"staff\",\n\"content\": \"홍길동\"\n}"
                this.socket.write(string: message)
            }.disposed(by: disposeBag)
        
        // 5. 웹 소켓을 통해 응답이 왔을때 rx로 처리하는 로직
        webSocket.rx.response
            .bind(with: self) { this, response in
                switch response {
                case .connected:
                    print("connected")
                    
                case .disconnected(let _):
                    print("disconnected")
                    
                case let .message(message):
                    print("message: \(message)")
                    label.text = mesaage
                    
                case let .data(data):
                    print("data \(data)")
                    
                case .pong:
                    print("pong")
                    
                default:
                    print("default")
                    
                }
            }.disposed(by: disposeBag)
    }
    
    init() {
        super.init(nibName: nil, bundle: nil)
        
        disposeBag = .init()
        
        configureUI()
        connect()
        bind()
    }
    
    required init(coder: NSCoder) {
        super.init(coder: coder)
        
        fatalError("fatalError")
    }
    
    deinit {
        disconnect()
    }
    
    // MARK: - UIComponents
    
    private lazy var button = UIButton().then {
        $0.setTitle("메시지 전송 버튼", for: .normal)
    }
    
    private lazy var label = UILabel().then {
        $0.text = "웹소켓 메시지 분석"
        $0.textAlignment = .center
    }
    
    private func configureUI() {
        view.addSubview(button)
        button.snp.makeConstraints {
            $0.top.left.right.equalToSuperview()
            $0.bottom.equalToSuperview().offset(-100)
        }
        
        view.addSubview(label)
        label.snp.makeConstraints {
            $0.top.equalTo(button.snp.bottom)
            $0.left.right.bottom.equalToSuperview()
        }
    }
}

// MARK: - 웹소켓
extension ViewController {
    private func connect() {
        let urlString = "{YOUR WEB SOCKET AVAIABLE SERVER}"
        var request = URLRequest(url: URL(string: urlString)!)
        
        // HTTPUpgrade error 발생 시 넣어주기
        request.addValue("{YOUR SERVER}", forHTTPHeaderField: "Origin")
        request.timeoutInterval = 10
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        socket = WebSocket(request: request)
        socket.connect()
    }
    
    private func disconnect() {
        socket.disconnect()
    }
    
}

 

'apple > RxSwift, ReactorKit' 카테고리의 다른 글

Extension Reactive (RxSwift)  (1) 2022.01.12
iOS RxDelegateProxy 만들어보기 #1  (0) 2022.01.12
RxSwift 06 RxDataSources  (0) 2021.08.19
Ch13. Intermediate RxCocoa  (0) 2021.08.12
RxSwift Ch12. Beginning RxCocoa  (0) 2021.08.12