简体   繁体   中英

RxKotlin with Socket.io in Android

What I trying to do is listen to socket data and convert into an observable string that my UI can Subscribe this event and do Change on UI

So far I created a class SocketConnection maintain in dagger connection happen properly and received data and able to do with interface correctly, but want to apply with rxkotlin.

Using Socket.io,kotlin

SocketConnection class

 class SocketConnection : SocketStreamListener {

    private var socket: Socket? = null

   var responseSocket :ResponseHandler?= null
    companion object {
        var instance = SocketConnection()

    }

    override fun createSocket(socketQuery: SocketQuery): Socket? {
        try {
            val okHttpClient = UnsafeOkHttpClient.getUnsafeOkHttpClient()
            IO.setDefaultOkHttpWebSocketFactory(okHttpClient)
            IO.setDefaultOkHttpCallFactory(okHttpClient)
            val opts = IO.Options()
            opts.reconnection = false
            opts.callFactory = okHttpClient
            opts.webSocketFactory = okHttpClient
            opts.query = "userID=" + socketQuery.userID + "&token=" + socketQuery.token
            socket = IO.socket(CommonContents.BASE_API_LAYER, opts)
            L.d("Socket object created")
        } catch (e: URISyntaxException) {
            L.e("Error creating socket", e)
        }
        return socket
    }

    override fun createSocketListener(socket: Socket) {
        L.d("inside the socket Listner")
        socket.connect()?.on(Socket.EVENT_CONNECT, {
            L.d("connected")
            listenSocketEvents()
            //socketDataListener()
            createMessageListener()

        })?.on(Socket.EVENT_DISCONNECT,
                {
                    L.d("disconnected")
                    return@on
                })

    }


    /**
     * function used to listen a socket chanel data
     */
    private fun listenSocketEvents() {


       /* socket?.on("1502", { args ->
      // This Will Work 
             L.d("Socket market depth event successfully")
            val socketData = args[0] as String
            L.d(socketData)
         //   instance.data = Observable.just(socketData)
            //data!!.doOnNext({ socketData })

            *//*
            data = args[0] as String
             for (i in 0 until arr.size) {
                 arr[i].socketStreamingData(data)
             }*//*

        })*/

    }

// This Will Not Work
    fun socketDataListener(): Observable<String>{
      return Observable.create({
          subscibe ->
         // L.d("Socket market depth event successfully")
            socket?.on("1502", { args ->
                L.d("Socket market depth event successfully")
                val socketData = args[0] as String
                subscibe.onNext(socketData)
            })

        })
    }

  }

Repository

fun getSocketData(): Observable<String> {
   // L.e("" + SocketConnection.instance.socketDataListener())
    return SocketConnection.instance.createMessageListener()
}

ViewModel

fun getSocketData(): Observable<String>{
    return groupRepository.getSocketData()
}

OnFragement (UI)

private fun getSocketUpdate(){
    subscribe(watchlistViewModel.getSocketData()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                L.d("SocketData :  " + it.count())

            }, {
                L.e("Error")
            }))
}

In this UI using disposable subscribe method into base class.

Please let me know what i doing wrong thanx in advance

Instead of creating an Observable every time a message is sent, I suggest using a Subject for that, since it has a similar "nature" as the Socket connection.

   val subject = PublishSubject.create<String>()
   ...

    fun listenSocketEvents() {
      socket?.on("1502") { args ->
        val socketData = args[0] as String
        subject.onNext(socketData)
      }
    }

    fun observable(): Observable<String>{
        return subject
    }

You can then listen to the changes on the subject via (repository layer etc not included, you'd have to do that yourself)

private fun getSocketUpdate() {
    disposable = socketConnection.observable()
            .subscribeOn(Schedulers.io())
            .observeOn(...)
            .subscribe({...}, {...})
}

As a side note, your singleton instance is not how you'd do that in kotlin. Instead of having an instance field in a companion object , you should make the declare the class as object SocketConnection .
This will automatically give you all singleton features. (I do not know whether it is smart to use a singleton with socket.io, but I assume that you know what you're doing :-) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM