Ի՞նչ լուծում եք օգտագործել WebSocket-ով աշխատելու համար:
sobes.tech AI
Պատասխան AI-ից
Նախագծերում, որտեղ պահանջվում էր ռեալ ժամանակի երկկողմ փոխազդեցություն, ես հաջողությամբ օգտագործել եմ URLSessionWebSocketTask:
Սա ինտեգրված լուծում է Network ֆրեյմվորկից, որը հասանելի է iOS 13-ից սկսած:
Առավելություններ URLSessionWebSocketTask-ի:
- Նատիվություն: Ինտեգրված է
URLSession-ի հետ, ինչը հեշտացնում է կապերի կառավարումը և ցանցային իրադարձությունների մշակումը: - Արդյունավետություն: Օպտիմիզացված է ցանցի աշխատանքի համար համակարգի մակարդակով:
- Հավատարիմություն: Ներքին pinga և pong մեխանիզմներ, ավտոմատ վերամիացում (համենայն դեպս, անհրաժեշտ է լրացուցիչ լոգիկա բարդ սցենարների համար):
- Անվտանգություն: Աջակցում է TLS-ին՝ փաթեթից դուրս:
Աշխատանքի հիմնական քայլերը՝
-
Ստեղծել
URLSessionWebSocketTaskօրինակ:// Ստեղծում է `URLSession`՝ ըստ ստանդարտ կարգավորումների let session = URLSession(configuration: .default) // WebSocket գործի սկիզբ let webSocketTask = session.webSocketTask(with: URL(string: "wss://example.com/socket")!) -
Սկսել կապը:
// Գործի վերականգնում՝ կապ հաստատելու համար webSocketTask.resume() -
Ուղարկել հաղորդագրություններ (տեքստ կամ բինար տվյալներ):
// Տեքստային հաղորդագրության ուղարկում 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)") } } -
Ստանալ հաղորդագրություններ. Սա ասինխրոն գործընթաց է:
// Հաղորդագրությունների ստացման ռեկուրսիվ ֆունկցիա 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() -
Կապի ցիկլի իրադարձությունների մշակումը (բացում, փակում, սխալներ)՝ օգտագործելով
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-ը՝ վերոնշյալ առավելությունների պատճառով։