ronp001 / SwiftRedis

A Swift client for Redis, providing asynchronous operation
MIT License
28 stars 3 forks source link

Subscription after entering background #5

Open szhernovoy opened 7 years ago

szhernovoy commented 7 years ago

Hi,

as I can see, redis is loosing connection when app enters background. When app goes back to foreground, I connect clients back. It works for SET and PUBLISH options, but I can't revive the subscription. It looks like we need an UNSUBSCRIBE command enabled. Or you suggest anything else?

ronp001 commented 7 years ago

Hey - sorry for the delay with this (I'm overloaded with other things at the moment).

Here's how I addressed this in my own app:

   // in AppDelegate:

    var notificationsConnection: RedisInterface? = nil

    func applicationDidBecomeActive(_ application: UIApplication) {
            subscribeToNetworkNotifications()
            ...
    }

    func applicationWillResignActive(_ application: UIApplication) {       
           disconnectNotifications()
           ...
    }

    func subscribeToNetworkNotifications()
    {
        guard notificationsConnection == nil else { return }

        self.notificationsConnection = RedisInterface(host: ConnectionParams.serverAddress, port: ConnectionParams.serverPort, auth: ConnectionParams.auth)

        notificationsConnection!.connect()

        notificationsConnection!.subscribe(ConnectionParams.notificationsChannelName, completionHandler: {
            success, key, result, cmd in
            guard success else {
                print("warning: error receiving value on subscription channel \(key)")
                return
            }
            ...
        })
    }

    func disconnectNotifications()
    {
        notificationsConnection?.disconnect()
        notificationsConnection = nil
    }
ronp001 commented 7 years ago

BTW - you're more than welcome to add an UNSUBSCRIBE command if you prefer. There are two ways this can be achieved:

Option 1: try using the RedisInterface.generic() function - pass "UNSUBSCRIBE" as the command string. Let me know if you run into any issues with it.

Option 2: add an .unsubscribe function to RedisInterface. Take a look at how the other commands were implemented - it's quite simple. Please open a pull request with your modified code if you do this so I can incorporate into the master branch.

rrotan commented 7 years ago

How to subscribe multi-channels?

rrotan commented 7 years ago

I've done it via GCD. (subscribing multi-channels)

fileprivate func beginRedisSuscribe() {

    let riSubscribe = RedisInterface(host: ConnectionParams.serverAddress, port: ConnectionParams.serverPort, auth: ConnectionParams.auth)

    riSubscribe.connect()

    var subscribeReturnCount = 0

    let conqueue = DispatchQueue(label: "queue1", attributes: .concurrent) 

    conqueue.async {

        riSubscribe.subscribe("CN", completionHandler: { success, channel, data, cmd in

            // this completion handler should be called several times.
            // the first time: to acknowledge that the subscribe operation was registered
            // the next two times:  in response to publish operations

            switch subscribeReturnCount {

            case 0:
                subscribeReturnCount += 1
                break

            default:

                if let responseData = data?.arrayVal?[2].dataVal {

                    let json = JSON(data: responseData)

                    print(json["qLastPrice"].intValue)
                    print(json["qChangeValue"].doubleValue)
                    print(json["qTotalQty"].intValue)

                    print("0-------------")

                }

                break
            }

        })
    }

    conqueue.async {

        riSubscribe.subscribe("CL", completionHandler: { success, channel, data, cmd in

            // this completion handler should be called several times.
            // the first time: to acknowledge that the subscribe operation was registered
            // the next two times:  in response to publish operations

            switch subscribeReturnCount {

            case 0:
                subscribeReturnCount += 1
                break

            default:

                if let responseData = data?.arrayVal?[2].dataVal {

                    let json = JSON(data: responseData)

                    print(json["qLastPrice"].intValue)
                    print(json["qChangeValue"].doubleValue)
                    print(json["qTotalQty"].intValue)

                    print("0-------------")

                }

                break
            }

        })
    }

}