Action Cable Client не получает ответ для канала onReceive в iOS - PullRequest
0 голосов
/ 02 июля 2019

В моем проекте есть требование, где пользователь загружает изображение на сервер, а загруженные изображения редактируются в бэкэнде, а пользователь получает новое изображение . Поскольку редактирование изображения занимает много времени, мы используем сокетное соединение, чтобы узнать, когда редактирование завершится.

Итак, мой текущий подход заключается в том, что, как только загрузка изображения завершится, я создаю канал с помощью клиентского кабеля Action и когда я получаю законченное изображение с сервера, я должен получить ответ на метод канала onReceive.

Но, делая это сейчас, я сталкиваюсь с двумя проблемами, первая главная проблема заключается в том, что обратный вызов onReceive иногда работает, а иногда нет. Второй , я всегда получаю неудачный ответ в обратном вызове. Это не проблема сервера, так как мы делаем то же самое в Android, и она отлично работает там. Любая помощь приветствуется. Ниже мой ActionCableManager класс.

class ActionCableManager {

    var client: ActionCableClient?
    var channel: Channel?
    let url = "wss://mysite.com/cable"
    let ChannelIdentifier = "MyChannel"

    init(){

        if self.client == nil{
            setupActionCableClient()
        }
    }


    func establishConnection() {
        guard let client = client else {
            return
        }
        client.connect()
    }

    func closeConnection() {
        self.client?.disconnect()
    }



    /*===============================================================================*/
    // MARK: - Setup connection
    /*===============================================================================*/

    func setupActionCableClient(){

        guard let urlString = URL(string: url) else {return}

        let headers = ["Origin":"Mysite address"]
        self.client = ActionCableClient(url: urlString, headers:headers)

        self.client?.willConnect = {
            print("Will Connect")
        }

        self.client?.onConnected = {
            print("Connected to \(String(describing: self.client?.url))")
        }

        self.client?.onDisconnected = {(error: ConnectionError?) in
            print("Disconnected with error: \(String(describing: error))")
        }

        self.client?.willReconnect = {
            print("Reconnecting to \(String(describing: self.client?.url))")
            return true
        }


    }

    func createChannel(_ roomId:String){

        let room_identifier = ["room_id" : roomId]
        self.channel = client?.create(ChannelIdentifier, identifier: room_identifier, autoSubscribe: true, bufferActions: true)

        self.channel?.onSubscribed = {
            print("Subscribed to \(self.ChannelIdentifier) with room Id=\(roomId)")
        }

        self.channel?.onReceive = {(data: Any?, error: Error?) in

            print("****** channel on receive data = \(String(describing: data))")
            if let error = error {
                print(error.localizedDescription)
                return
            }
        }

    }

}

И вот как я это использую на своем MainViewController:

let actionCableManager = ActionCableManager()

 override func viewDidLoad() {
    super.viewDidLoad()

    actionCableManager.establishConnection()
  }


//To upload image to server and register Action cable channel
func uploadImage(){

  //Some code to upload the image

//check for image upload status
if let httpResponse = response as? HTTPURLResponse {

            //Image upload was successful
                if httpResponse.statusCode == 200{

                    DispatchQueue.main.async {

                        self.actionCableManager.createChannel(self.roomId)
                    }
                }
           }
}

Ниже приведен фрагмент кода Android, который работает:

// 1. Setup
URI uri = new URI("wss://mysite.com/cable");

Consumer.Options options=new Consumer.Options();
 options.headers = new ArrayMap<>();
 options.headers.put("Origin","My Site address");
 Consumer consumer = ActionCable.createConsumer(uri,options);

// 2. Create subscription
 Channel appearanceChannel = new Channel("MyChannel");
 appearanceChannel.addParam("room_id",randomString);
 Subscription subscription = consumer.getSubscriptions().create(appearanceChannel);


subscription
    .onConnected(new Subscription.ConnectedCallback() {
        @Override
        public void call() {
            // Called when the subscription has been successfully completed
        }
    }).onRejected(new Subscription.RejectedCallback() {
        @Override
        public void call() {
            // Called when the subscription is rejected by the server
        }
    }).onReceived(new Subscription.ReceivedCallback() {
        @Override
        public void call(JsonElement data) {
            **//Gets a success response here with transformed image URL**
        }
    }).onDisconnected(new Subscription.DisconnectedCallback() {
        @Override
        public void call() {
            // Called when the subscription has been closed
        }
    }).onFailed(new Subscription.FailedCallback() {
        @Override
        public void call(ActionCableException e) {
            // Called when the subscription encounters any error
        }
    });

// 3. Establish connection
consumer.connect();

PS: я использую эту библиотеку github для ActionCableClient

...