Разъем не подключен в iOS Swift? - PullRequest
2 голосов
/ 23 января 2020

Я пытался подключить сервер через сокет, но он отказывается подключаться. Здесь я пытаюсь отправить параметр запроса (токен) с базовым URL для подключения к серверу. Но, тем не менее, он не подключается.

Вот ошибка вывода консоли:

manager  <SocketIO.SocketManager: 0x283542f00>
2020-01-23 17:59:12.872248+0530 A8FlowSampleApp[34442:7736351] LOG SocketIOClient{/}: Handling event: statusChange with data: [connecting, 2]
2020-01-23 17:59:12.872415+0530 A8FlowSampleApp[34442:7736351] LOG SocketIOClient{/}: Joining namespace /
2020-01-23 17:59:12.872543+0530 A8FlowSampleApp[34442:7736351] LOG SocketManager: Tried connecting socket when engine isn't open. Connecting
2020-01-23 17:59:12.872621+0530 A8FlowSampleApp[34442:7736351] LOG SocketManager: Adding engine
2020-01-23 17:59:12.873836+0530 A8FlowSampleApp[34442:7736455] LOG SocketEngine: Starting engine. Server: https://base url/event-stream/
2020-01-23 17:59:12.874735+0530 A8FlowSampleApp[34442:7736455] LOG SocketEngine: Handshaking
2020-01-23 17:59:13.452879+0530 A8FlowSampleApp[34442:7736457] ERROR SocketEngine: Invalid HTTP upgrade. code=404, type=upgradeError
2020-01-23 17:59:13.455416+0530 A8FlowSampleApp[34442:7736351] LOG SocketIOClient{/}: Handling event: websocketUpgrade with data: [["server": "nginx/1.17.4", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "content-length": "153", "vary": "Accept-Encoding", "content-type": "text/html", "connection": "keep-alive", "date": "Thu, 23 Jan 2020 12"]]
2020-01-23 17:59:13.455832+0530 A8FlowSampleApp[34442:7736351] ERROR SocketManager: Invalid HTTP upgrade. code=404, type=upgradeError
2020-01-23 17:59:13.456085+0530 A8FlowSampleApp[34442:7736351] LOG SocketIOClient{/}: Handling event: error with data: ["Invalid HTTP upgrade. code=404, type=upgradeError"]
2020-01-23 17:59:13.456546+0530 A8FlowSampleApp[34442:7736351] LOG SocketManager: Starting reconnect
2020-01-23 17:59:13.456796+0530 A8FlowSampleApp[34442:7736351] LOG SocketManager: Trying to reconnect
2020-01-23 17:59:13.457076+0530 A8FlowSampleApp[34442:7736351] LOG SocketIOClient{/}: Handling event: reconnectAttempt with data: [100]
2020-01-23 17:59:13.457298+0530 A8FlowSampleApp[34442:7736351] LOG SocketManager: Adding engine
2020-01-23 17:59:13.458324+0530 A8FlowSampleApp[34442:7736351] LOG SocketEngine: Engine is being released
2020-01-23 17:59:13.460873+0530 A8FlowSampleApp[34442:7736351] LOG SocketManager: Scheduling reconnect in 20.375904394158646s

Вот код сокета:

import Foundation
import UIKit
import SocketIO

class SocketIOManager: NSObject {
    static let shared = SocketIOManager()

    static let authToken = UserDefaults.standard.string(forKey: "authToken")
    static let bearerToken: String = "?token=Bearer " + (authToken ?? "")
    static let newBaseURL = UserDefaults.standard.string(forKey: "baseURL")!
    //static let v = newBaseURL + "/event-stream/?token=\(bearerToken)"

    static let v = newBaseURL + "/event-stream/"

    var socket: SocketIOClient!

    // defaultNamespaceSocket and swiftSocket both share a single connection to the server
    let manager = SocketManager(socketURL: URL(string: v)!, config: [.log(true), .compress, .path("?token=\(bearerToken)")])

    override init() {
        super.init()

        socket = manager.defaultSocket
    }

    func connectSocket() {
        print("manager ", manager)

        self.manager.config = SocketIOClientConfiguration(
            arrayLiteral:  .secure(true), .log(true), .forceNew(true), .reconnects(true), .reconnectAttempts(100), .forceWebsockets(true)
        )
        socket.connect()
    }

    func receiveMsg() {
        socket.on("chatevent") { (dataArray, ack) in
            print(dataArray.count)
        }
    }
}//class

Как подключить сокет и получить сообщение от сервер?

Отредактированная версия:

 import SocketIO


 class SocketIOManager: NSObject {




open class SocketConnection {

    public static let default_ = SocketConnection()
    let manager: SocketManager
    public init() {


        let authToken = UserDefaults.standard.string(forKey: "authToken")
        let bearerToken: String = authToken ?? ""
        let param:[String:Any] = ["token": "Bearer " + bearerToken]
        let route = "/event-stream/"

        let socketURL: URL = Utility().URLforRoute(route: route, params: param)! as URL
        manager = SocketManager(socketURL: socketURL, config: [.log(true), .compress, .forcePolling(false), .forceNew(true), .reconnects(true), .reconnectAttempts(100), .forceWebsockets(true)])
        manager.config = SocketIOClientConfiguration(arrayLiteral: .connectParams(param), .secure(true))
    }
}
 public func connectSocket(){
    let socket = SocketConnection.default_.manager.defaultSocket
    if socket.status != .connected{
        socket.connect()
    }
    socket.on(clientEvent: .connect) {data, ack in

        print(data)
        print(ack)
        print("socket connected")
   //            self.getFinishAcknowledgement()
    }
    socket.on(clientEvent: .disconnect) {data, ack in

    }
    socket.on("unauthorized") { (data, ack) in
        print(data)
        print(ack)
        print("unauthorized user")
    }

    socket.on("chatevent") { (dataArray, ack) in

                print(dataArray.count)

            }
}
private func disconnectSocket(){
    let socket = SocketConnection.default_.manager.defaultSocket
    socket.disconnect()
}


 }


 extension NSObject {

 func URLforRoute(route: String,params:[String: Any]) -> NSURL? {



    let newBaseURL = UserDefaults.standard.string(forKey: "baseURL")!
        //static let v = newBaseURL + "/event-stream/?token=\(bearerToken)"

    let v = newBaseURL

    if let components: NSURLComponents  = NSURLComponents(string: (v+route)){
        var queryItems = [NSURLQueryItem]()
        for(key,value) in params {
            queryItems.append(NSURLQueryItem(name:key,value: "\(value)"))
        }
        components.queryItems = queryItems as [URLQueryItem]?
        return components.url as NSURL?
    }
    return nil
}

@objc class Utility: NSObject{
       static let main = Utility()
       fileprivate override init() {}


   }


 }

1 Ответ

3 голосов
/ 28 января 2020

Я использовал pod SocketIO для подключения и получения сообщений от сервера, и это прекрасно работает.

Здесь pod для установки,

pod 'Socket.IO-Client-Swift', '~ > 15.1.0 '

import SocketIO


class SocketIOManager: NSObject {

    open class SocketConnection {

        public static let default_ = SocketConnection()
        let manager: SocketManager
        private init() {
            let param:[String:Any] = [:]
            let route = "YOUR_ROUTE"
            let socketURL: URL = Utility.URLforRoute(route: route, params: param)! as URL
            manager = SocketManager(socketURL: socketURL, config: [.log(true), .compress])
            manager.config = SocketIOClientConfiguration(arrayLiteral: .connectParams(param), .secure(true))
        }
    }
    private func connectSocket(){
        let socket = SocketConnection.default_.manager.defaultSocket
        if socket.status != .connected{
            socket.connect()
        }
        socket.on(clientEvent: .connect) {data, ack in

            print(data)
            print(ack)
            print("socket connected")
            self.getFinishAcknowledgement()
        }
        socket.on(clientEvent: .disconnect) {data, ack in

        }
        socket.on("unauthorized") { (data, ack) in
            print(data)
            print(ack)
            print("unauthorized user")
        }
    }
    private func disconnectSocket(){
        let socket = SocketConnection.default_.manager.defaultSocket
        socket.disconnect()
    }
    private func emitLatLng(){
        let socket = SocketConnection.default_.manager.defaultSocket
        if socket.status != .connected{return}
        let params:[String:Any] = ["lat":"lat","lng":"lng","rideId":"rideId"] as Dictionary
        print(params)
        socket.emitWithAck("Acknowledgement", params).timingOut(after: 5) {data in
            print(data)
        }
    }
    private func emitEndRide(){
        let socket = SocketConnection.default_.manager.defaultSocket
        let param:[String:Any] = ["rideId":"rideId"] as Dictionary
        socket.emitWithAck("Acknowledgement", param).timingOut(after: 5) {data in
            print(data)
        }
    }
    private func getFinishAcknowledgement(){
        let socket = SocketConnection.default_.manager.defaultSocket
        socket.on("Acknowledgement") {data, ack in
            print(data)
            socket.disconnect()
        }
    }
}

Функция для параметра запроса:

extension Utility{
    static func URLforRoute(route: String,params:[String: Any]) -> NSURL? {
        if let components: NSURLComponents  = NSURLComponents(string: route){
            var queryItems = [NSURLQueryItem]()
            for(key,value) in params {
                queryItems.append(NSURLQueryItem(name:key,value: "\(value)"))
            }
            components.queryItems = queryItems as [URLQueryItem]?
            return components.url as NSURL?
        }
        return nil
    }
}

Для утилиты добавьте:

@objc class Utility: NSObject{
    static let main = Utility()
    fileprivate override init() {}
}

Затем создайте расширение утилиты и добавьте выше функция "URLForRoute" в этом расширении.

Изменения в вашем коде:

До

let authToken = UserDefaults.standard.string(forKey: "authToken")
let bearerToken: String = "Bearer " + (authToken ?? "")
let param:[String:Any] = ["token": bearerToken]

После

let authToken = UserDefaults.standard.string(forKey: "authToken")
let bearerToken: String = authToken ?? ""
let param:[String:Any] = ["Authorization": bearerToken]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...