Socket.iO comunication between iOS app and nodeJS

반응형
728x90
반응형
photo by vbflash
 
 
Introduction

이번 포스팅은 길었던 iOS chatting App UI를 마치고, 본적격으로 socket.iO를 이용하여 통신을 주고 받는 방법에 대해 알아보도록 하겠습니다. 이것저것 테스트를 많이하다보니, 소스코드가 많아져 혼란스러운 부분이 있어 포스팅에 해가가지 않을까 했지만 다행히 소스코드를 백업 해둬서 이렇게 글을 쓸 수 있네요. 블로그 쓰는 시점에 macOS Big sur 가 업데이트 되고 있는데, 향후 작업하시는 부분에 있어 문제가 되지 않을까도 걱정됩니다. 하지만, 발생하는 오류가 있으시면 댓글 달아주세요! 현재 작업 중인 부분에 대해서는 질답이 가능하니깐요...!! 그럼 socket.io를 이용한 통신방법에 대해 알아볼까요?
 

 

 

 

 
socket.io based iOS client App (with xcode)

  다른 멀티플랫폼을 이용하여 socket.io를 이용하면서 접근을 할 수 있지만, 본 블로그에서는 xcode기반으로 계속사용하고 있습니다. 참고로, 멀티플랫폼과 관련된 작업은 작업을 빨리해야할 때 진행하며 포스팅 하도록하겠습니다. 
 
먼저, socket.io library를 이용하기 위해서 cocoapods을 이용합니다.  Socket.IO-Client-Swift을 이용할 예정입니다. 해당 페이지에 접속하여 다른 정보들도 함께 알아봐 주시기 바랍니다. 
 
cocoapods 설치 및 사용방법은 따로 포스팅을 해두었으니 참고 바랍니다. 
 
 
이제 cocoapods에서 Socket.IO-Client-Swift Library를 사용하기위해 아래와 같은 순서대로 작업을 하시면 됩니다. 
 
  • Xcode를 이용하여 iOS App Project 생성
  • terminal 실행 후, 생성된 폴더로 이동 후 아래의 명령어를 수행
 
#명령어
pod init
 
생성된 profile 에 아래 내용 추가하시면 됩니다. 
 
# Profile
use_frameworks!
target 'YourApp' do
    pod 'Socket.IO-Client-Swift', '~> 15.2.0'
end
 
#명령어
pod install
 
이제 다음 단계로 넘어가서 xcode를 실행하시면 됩니다. 
 
 
xCode Project

*.xcworkspace를 open 하여 이제 작업을 수행하도록 하겠습니다.  먼저 SockMgr.swift를 생성 후 아래와 같이 추가하시면 됩니다. 
 
SockMgr.swift
//
//  SockMgr.swift
//  SocketIOChatExR01
//
//  Created by vbflash on 2020/09/23.
//  Copyright © 2020 vbflash. All rights reserved.
//

import Foundation
import SocketIO


let manager = SocketManager(socketURL: URL(string: "http://localhost:3014")!, config: [.log(false), .compress, .forceWebsockets(true)])


class SockMgr {

// ... 생략

}
 
이때, IPAddress 및 PORT 설정은 서버에 맞춰서 작성하셔야 합니다. 그리고 다른 PC Server를 이용할 경우 방화벽을 확인해주시면 됩니다. 또한, 공유기에서도 방화벽을 동일하게 해제해주지 않는 경우, 접속자체가 안되니 꼭 확인하고 넘어가주시기 바랍니다. 
 

 

 

 

SockMgr.swift(계속)
//
//  SockMgr.swift
//  SocketIOChatExR01
//
//  Created by vbflash on 2020/09/23.
//  Copyright © 2020 vbflash. All rights reserved.
//


import Foundation
import SocketIO


let manager = SocketManager(socketURL: URL(string: "http://localhost:3014")!, config: [.log(false), .compress, .forceWebsockets(true)])


class SockMgr {
    
    // singleton
    static let mInstance = SockMgr()
    private init() {}

    // 생략 ... 
}
 
일단 가장먼저 singleton을 이용하도록 하겠습니다.  그리고 이제 통신 테스트를 하기위해 아래의 코드를 추가 합니다. 
 
SockMgr.swift(계속)
// 생략 ...
    
    func establishConnection() {
        socket.connect()
        
        let message: [String: Any] = [
            "sender": "from iOS",
            "recepient": "ALL",
            "command": "chat",
            "type":"text",
            "data": "한글테스트"
        ]
        
        socket.on(clientEvent: .connect) {data, ack in
            print("socket connected: http://localhost:3014")
            
            self.socket.emit("message", message)
            print("emited on TestSock()")
        }

        print("log: establishConnection")
    }

    func closeConnection() {
        socket.disconnect()
    }

// 생략 ...
 
establishConnection() 함수를 만들어서 JSON형태대로 message를 생성합니다. 그리고 socket.on() 함수를 이용하여 서버에 접속 후 emit()를 이용하여 메시지를 전달하고 있습니다.  서버에서 전달 받은 값은 마지막에 확인하도록 하고, App이 실행될 때, 바로 함수를 수행할 수 있도록 다음 코드를 추가합니다. 
 
AppDelegate.swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {    

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.        
        
        SockMgr.mInstance.establishConnection()

        return true
    }
 
application() 함수를 잘보고 추가 해주시면 됩니다. 그리고 singleton을 이용하여 establishConnection() 함수를 호출 하면 끝. 
 
그럼 이제 결과물을 확인 해보도록 할까요? 
 

 

 

 
# 결과확인

아래의 결과는 Xcode 및 brackets에 출력되는 로그 결과 입니다. 
 
# Xcode 출력
log: establishConnection
socket connected: http://localhost:3014
emited on TestSock()
 
 
# nodeJS 출력 결과 (by brackets)
connection info : { address: '::1', family: 'IPv6', port: 59896 }

message 이벤트를 받았습니다.
{
command: 'chat',
type: 'text',
sender: 'from iOS',
recepient: 'ALL',
data: '한글테스트'
}
'나를 포함한 모든 클라이언트에게 message 이벤트를 전송합니다.'
 
다음으로 localhost:3014로 접속하여 출력된 결과를 확인 하면 다음과 같습니다. 
 
 
참 쉽죠...? 포스팅하기까지는 참 어렵고 귀찮고 그런데...
서버는 nodeJS에 있는 예제소스코드를 이용하시면 됩니다. 
 
그리고 아직 끝나지 않았습니다.  결과가 제대로 나오지 않는 경우가 있는데 permission을 Xcode에 추가해야하더군요. 기타 온라인 자료를 확인해봐도 추가해놓은 자료들이 없더라구요. 이것때문에 혹여나 싶어 추가하고 갑니다. 
 
 
Xcode에서 네트워크 Permission 추가 하기 (App transport Security Settings)

 
  • 문제점
    • App Transport Security policy requires the use of a secure connection ~ 와 같은 오류가 발생할 경우, 아래와 같이 해결함 
  • Info.plist 내부에 아래의 항목을 추가 함
    • Allow Arbitrary Loads : YES
    • App Transport Security Settings
 
 
xcode : tried emitting when not connected swift

그 외에 발생하는 오류들은 간단히 요약으로 추가합니다. 
 
socket.on("connect") { _, _ in
        print("socket connected")
        socket.emit("your_event", jsonObject)
    }
 
Sockets require a connection before emit is called. For this purpose Socket.IO has a listener socket.on ("connect"). So after we got status connected we can emit.
728x90
반응형

댓글

Designed by JB FACTORY