본문 바로가기
프로그래밍/iOS-Swift

[SWIFT] Web Socket (Stomp)

by 채연2 2021. 7. 9.

오늘은 웹소켓, 그중에서도 stomp를 다뤄보려고 한다.

이유는.. stomp client 쪽을 개발하면서 진짜 삽질도 많이 하고 게다가 swift stomp web socket에 대한 정보가 많이 없기 때문이었다..

그래서 내가 경험하고 부족한 부분들은 어떻게 처리했는지 포스팅 해보려고 한다.

 

사용 라이브러리 : StompClientLib

 

 

Podfile

...
target 'Project_Name' do
  pod 'StompClientLib'
...

다음과 같이 작성하고 pod install !

 

 

기본 예제

import StompClientLib

class StompManager {
    static let shared:StompManager = StompManager()
    
    private let url = URL(string: "웹소켓 서버 주소")
    private var socketClient:StompClientLib? = nil
    
    func registerSocket() {
    	if socketClient == nil {
        	socketClient?.openSocketWithURLRequest(request: NSURLRequest(url: url! as URL), delegate: self)
    	}
    }
    
    func subscribe() {
        if socketClient != nil, socketClient?.isConnected() {
            print("\(stompTag)Subscribe Topic")
            socketClient?.subscribe(destination: "구독할 토픽")
        }
    }
    
    func disconnect() {
        if socketClient != nil, socketClient!.isConnected() {
            socketClient?.disconnect()
        }
    }
}

extension StompManager:StompClientLibDelegate {
	func stompClientDidDisconnect(client: StompClientLib!) {
        print("\(stompTag)stomp socket is disconnected")
        socketClient = nil
    }
    
    func stompClientDidConnect(client: StompClientLib!) {
        print("\(stompTag)stomp socket is connected")
        
        //원하는 토픽 구독
        subscribe()
    }
    
    func serverDidSendError(client: StompClientLib!, withErrorMessage description: String, detailedErrorMessage message: String?) {
        print("\(stompTag)Error send : \(String(describing: description)), \(String(describing: description))")

        socketClient?.disconnect()
        socketClient = nil
        registerSocket()
    }
    
    func stompClient(client: StompClientLib!, didReceiveMessageWithJSONBody jsonBody: AnyObject?, akaStringBody stringBody: String?, withHeader header: [String : String]?, withDestination destination: String) {
        print("\(stompTag)** Destination : \(destination)")
        print("\(stompTag)JSON Body : \(String(describing: stringBody))")
        
        if stringBody == nil {
            return
        }
        
        guard let data = stringBody!.data(using: .utf8) else {
            return
        }
    }
}

우선 기본적인 코드는 위와 같다. 개발하면서 내가 발견한 문제는 2가지이다.

 

 

 

첫 번째 문제

바로... unsubscribe가 제대로 구현되어 있지 않다는 점....

socketClient?.unsubscribe(destination: "구독한 토픽")

위와 같은 unsubscribe함수가 존재하지만, 막상 사용하면 java null exception 에러가 뜬금없이 나타난다..

그래서 내가 해결한 방법은 그냥 disconnect 하고 다시 reconnect 하는 것!!

근데 이 방법도 문제가 있다.

3개의 토픽을 구독을 했는데 그중 1개만 해제하고 싶을 때의 방법이 없다는 것이다... 아직 나도 해결하지 못했다..

 

 

 

 

두 번째 문제

하트비트 옵션이 적용되지 않는다는 점.

만일 이 라이브러리를 사용한다면 제공되는 함수로는 heartbear 관련된 함수가 없고, 수많은 구글링 끝에 발견한 답은 connect 시  header에 옵션으로 넣으라는 것이었다.

socketClient?.openSocketWithURLRequest(
		request: NSURLRequest(url: url! as URL),
        delegate: self,
        connectionHeaders: ["heart-beat":"0,1000"]
)

위와 같이 connectionHeaders에 넣어서 해봐도 일정 시간 뒤에 연결이 끊겨버린다.

그래서 해결 방법은... 서버에게 핑퐁 메시지 정의를 해달라는 것뿐이다 ㅜㅜ

 

 

 

나는 위의 두 가지 문제들을 각각 내 방식대로 해결하여 아직은 잘 사용 중이긴 하다. 하지만 후에 문제가 분명 생길 것이다...

그건 그때 가서 봐야지....

320x100

댓글