iOS - SocketIO

이한솔·4일 전
0

iOS 앱개발 🍏

목록 보기
45/49

SocketIO

먼저 Socket.IO를 사용해서 웹소켓 연결을 설정하고 통신을 처리하는 코드를 살펴보자!

import SocketIO

// SocketManager: 소켓IO에서 소켓 연결을 관리하는 주요 객체
// 로컬서버에서 8080포트를 통해 웹소켓 서버에 연결
// config: [.log(true): 로깅활성화 / 소켓 연결, 메시지 전송, 수신 등과 관련된 다양한 활동을 콘솔에 출력하는 것을 의미
// .compress: 데이터압축 / 소켓을 통해 전송되는 데이터를 압축하여 전송하는 것을 의미
let manager = SocketManager(socketURL: URL(string: "http://localhost:8080")!, config: [.log(true), .compress])

// 기본 소켓을 가져옴 
let socket = manager.defaultSocket

// socket.on로 소켓 연결, .connect 이벤트가 발생 시 "socket connected" print함
socket.on(clientEvent: .connect) {data, ack in
    print("socket connected")
}

// "currentAmount" 이벤트가 수신되었을 때
socket.on("currentAmount") {data, ack in

// data 배열에서 첫 번째 요소를 Double로 변환하여 cur 변수에 저장
    guard let cur = data[0] as? Double else { return }
    
    // emitWithAck 메소드: 클라이언트에서 이벤트를 서버로 전송하고, 서버로부터 확인 응답을 기다리는 기능 제공
    // 클라이언트에서 서버로 "canUpdate" 이벤트와 cur 변수 전달    
    // 타임아웃 없음
    socket.emitWithAck("canUpdate", cur).timingOut(after: 0) {data in
    
    // 서버에서 받은 데이터의 첫번째 요소 확인, 데이터가 없거나 SocketAckValue가 noAck이면 타임아웃 처리 
        if data.first as? String ?? "passed" == SocketAckValue.noAck {
            // Handle ack timeout 
        }

// 데이터가 있으면 서버로 "update" 이벤트와 cur 변수에 2.50를 증가시켜서 새로운 데이터 전달 
        socket.emit("update", ["amount": cur + 2.50])
    }

// ack: 클라이언트가 서버로부터 이벤트를 수신했을 때 함께 제공되는 확인 응답, 이 객체를 이용해서 서버에 응답을 보냄
// 클라이언트가 서버로부터 "currentAmount" 이벤트를 수신했음을 확인 응답으로 보냄
    ack.with("Got your currentAmount", "dude")
}

// 소켓 연결 시작
socket.connect()


SocketIO Version

SocketIO 버전 변화를 살펴보자!

Socket.IO 12.x

클라이언트 생성: 소켓 클라이언트를 직접 생성하고 관리했다.
네임스페이스: 각 클라이언트는 고유의 엔진을 가졌고, 네임스페이스를 사용하기 위해 여러 개의 클라이언트를 생성해야 했다.

let defaultSocket = SocketIOClient(socketURL: URL(string: "http://localhost:8080")!)
let namespaceSocket = SocketIOClient(socketURL: URL(string: "http://localhost:8080")!, config: [.nsp("/swift")])

💡 Namespace와 Room이란?
Namespace란 namespace안에 있는 소켓들을 room으로 쪼개어 나눈 것이다.
서버에서 제공하는 서비스나 기능들을 구분해서 사용하거나, 클라이언트가 특정 메시지를 받을 필요가 없는 경우를 구분해서 관리할 수 있다.
Room이란 Namespace의 하위 개념으로 예를 들어, /chat 네임스페이스 안에는 general, private, group1 등 여러 개의 룸이 있을 수 있다. 특정 룸에 신호를 보내면 룸 안의 소켓들은 신호를 받지만, 다른 룸에 소속된 소켓들은 신호를 받지 못한다.



Socket.IO 13.x

SocketManager 도입: 소켓 연결을 관리하는 SocketManager 객체가 도입되었다.
클라이언트 생성: 직접 소켓 클라이언트를 생성하는 대신 SocketManager를 통해 소켓을 생성하고 관리한다.
네임스페이스: 네임스페이스가 필요하지 않으면 defaultSocket 속성을 사용하고, 네임스페이스가 필요한 경우 socket(forNamespace:) 메서드를 호출한다.

let manager = SocketManager(socketURL: URL(string: "http://localhost:8080")!)
let defaultSocket = manager.defaultSocket
let namespaceSocket = manager.socket(forNamespace: "/swift")

socket(forNamespace:) 메소드를 여러번 호출해도 처음 호출시 반환된 동일한 소켓 인스턴스를 반환하기 때문에 같은 네임스페이스 내에서 여러 개의 소켓이 필요할 때는 여러개의 매니저를 사용해야 한다.

class Manager {
    let socketManager = SocketManager(socketURL: someURL)

    func addHandlers() {
        let socket = socketManager.socket(forNamespace: "/swift")

        // 핸들러 추가
    }
}


Socket.IO에서 connect() 메서드 사용 방법

  1. SocketManager에서 connect() 호출
    SocketManager가 기본 네임스페이스("/") 소켓을 통해 서버에 연결되고
    기본 네임스페이스가 아닌 다른 소켓들은 자동으로 연결되지 않는다.
    각각의 소켓에 대해 개별적으로 connect()를 호출해야한다.
let manager = SocketManager(socketURL: myURL)
manager.connect()
  1. 생성된 소켓에서 connect() 호출
    기본 네임스페이스 소켓과 해당 네임스페이스 소켓 모두 연결된다.
let manager = SocketManager(socketURL: myURL)
let namespaceSocket = manager.socket(forNamespace: "/swift")
namespaceSocket.connect()


Socket.IO 16.x

Objective-C가 지원되지않고 Swift를 사용해야 한다.
클라이언트는 여러 버전의 Socket.IO를 지원하고 기본적으로 Socket.IO 3 서버를 지원한다. 서버가 Socket.IO 2인 경우에는 매니저에 .version(.two) 옵션을 전달해야 한다.

let manager = SocketManager(socketURL: URL(string: "http://localhost:8087/")!, config: [.version(.two)])

0개의 댓글