Sobes.tech
Middle

Ի՞նչ լուծում եք օգտագործել WebSocket-ով աշխատելու համար:

sobes.tech AI

Պատասխան AI-ից

Նախագծերում, որտեղ պահանջվում էր ռեալ ժամանակի երկկողմ փոխազդեցություն, ես հաջողությամբ օգտագործել եմ URLSessionWebSocketTask:

Սա ինտեգրված լուծում է Network ֆրեյմվորկից, որը հասանելի է iOS 13-ից սկսած:

Առավելություններ URLSessionWebSocketTask-ի:

  • Նատիվություն: Ինտեգրված է URLSession-ի հետ, ինչը հեշտացնում է կապերի կառավարումը և ցանցային իրադարձությունների մշակումը:
  • Արդյունավետություն: Օպտիմիզացված է ցանցի աշխատանքի համար համակարգի մակարդակով:
  • Հավատարիմություն: Ներքին pinga և pong մեխանիզմներ, ավտոմատ վերամիացում (համենայն դեպս, անհրաժեշտ է լրացուցիչ լոգիկա բարդ սցենարների համար):
  • Անվտանգություն: Աջակցում է TLS-ին՝ փաթեթից դուրս:

Աշխատանքի հիմնական քայլերը՝

  1. Ստեղծել URLSessionWebSocketTask օրինակ:

    // Ստեղծում է `URLSession`՝ ըստ ստանդարտ կարգավորումների
    let session = URLSession(configuration: .default)
    // WebSocket գործի սկիզբ
    let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    
  2. Սկսել կապը:

    // Գործի վերականգնում՝ կապ հաստատելու համար
    webSocketTask.resume()
    
  3. Ուղարկել հաղորդագրություններ (տեքստ կամ բինար տվյալներ):

    // Տեքստային հաղորդագրության ուղարկում
    webSocketTask.send(.string("Hello, world!")) { error in
        if let error = error {
            print("Սխալ ուղարկման ժամանակ՝ \(error)")
        }
    }
    
    // Բինար տվյալների ուղարկում
    let dataToSend = Data([1, 2, 3])
    webSocketTask.send(.data(dataToSend)) { error in
        if let error = error {
            print("Սխալ ուղարկման ժամանակ՝ \(error)")
        }
    }
    
  4. Ստանալ հաղորդագրություններ. Սա ասինխրոն գործընթաց է:

    // Հաղորդագրությունների ստացման ռեկուրսիվ ֆունկցիա
    func receiveMessage() {
        webSocketTask.receive { result in
            switch result {
            case .failure(let error):
                print("Սխալ ստացման ժամանակ՝ \(error)")
                // Սխալի մշակումը, հնարավոր է՝ վերամիացում
            case .success(let message):
                switch message {
                case .string(let text):
                    print("Ստացվել է տեքստային հաղորդագրություն՝ \(text)")
                case .data(let data):
                    print("Ստացվել են բինար տվյալներ՝ \(data)")
                @unknown default:
                    fatalError("Անհայտ հաղորդագրության տեսակ")
                }
                // Շարունակել լսել հաղորդագրությունները
                self.receiveMessage()
            }
        }
    }
    
    // Սկսել լսողը
    receiveMessage()
    
  5. Կապի ցիկլի իրադարձությունների մշակումը (բացում, փակում, սխալներ)՝ օգտագործելով URLSessionWebSocketDelegate դելեգատը:

    // Դելեգատի օրինակ
    class WebSocketHandler: NSObject, URLSessionWebSocketDelegate {
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
            print("Կապը բացված է")
            // Հետո հաղորդագրությունների ստացումը
            receiveMessage() // ենթադրվում է, որ `receiveMessage`-ը սահմանված է
        }
    
        func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
            let reasonString = reason.flatMap { String(data: $0, encoding: .utf8) } ?? "Անհայտ պատճառ"
            print("Կապը փակվել է կոդով \(closeCode.rawValue), պատճառ՝ \(reasonString)")
            // Վերամիացման կամ աշխատանքի ավարտի լոգիկա
        }
    
        // Սեսիայի սխալների մշակումը
        func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
            if let error = error {
                print("Աշխատանքը ավարտվել է սխալի հետ՝ \(error)")
                // Ավելին՝ սխալների մշակման լոգիկա
            }
        }
    }
    
    // Սեսիա ստեղծել՝ օգտագործելով դելեգատ
    let delegate = WebSocketHandler()
    let sessionWithDelegate = URLSession(configuration: .default, delegate: delegate, delegateQueue: OperationQueue())
    let webSocketTaskWithDelegate = sessionWithDelegate.webSocketTask(with: URL(string: "wss://example.com/socket")!)
    

Նաև օգտագործել եմ երրորդ կողմի գրադարաններ, ինչպիսիք են Starscream-ը, երբ պահանջվում էր աջակցել ավելի հին iOS տարբերակներին կամ որոշ ֆունկցիոնալ հնարավորություններ, որոնք բացակայում էին նատիվ լուծումներից (օրինակ՝ ավտոմատ վերամիացում՝ էքսպոնենցիալ սպասումով): Սակայն, եթե հնարավոր է, ես նախընտրում էի URLSessionWebSocketTask-ը՝ վերոնշյալ առավելությունների պատճառով։