0

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

Rupesh
  • 51
  • 2
  • 10
  • what exactly isn't working? and which socketIO library are you using? – Lovis Mar 14 '18 at 09:09
  • I want socket lister string should convert in Observable then I can subscribe on my view. using Socket IO io.socket:socket.io-client:1.0.0 Converting in Observable is not working. socket working properly – Rupesh Mar 14 '18 at 11:09
  • what is `SocketConnection`? I can't find it in that library – Lovis Mar 14 '18 at 12:03
  • 1
    This is my class name i will update question with full socket class – Rupesh Mar 14 '18 at 12:05

1 Answers1

0

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 :-) )

Lovis
  • 9,513
  • 5
  • 31
  • 47
  • Tanx Lovis .. in fact before u giving an answer, I will already be done with same, but u answer is better than mine with perfection. Thanks very much – Rupesh Mar 15 '18 at 05:28
  • @Rupesh great that I could help! :-) – Lovis Mar 15 '18 at 07:26