Написание чата Android

Написание чата Android

/stackoverflow

Вопрос:
Имеется задача - написать чат на android. Так же присутствует чат-сервер. Насколько я понял все нужно будет делать на сокетах. Но я не могу понять с чего начать :( Во-первых сложно найти адекватно работающую библиотеку или способ который даст ожидаемый результат. Надеялся что получится сделать все через scarlet от Tinder но что-то пошло не так, и зависимости не подключились адекватно. Появилось много проблем после установки требуемой версии java в build.gradle. Есть много библиотек и еще больше кустарных способов, но большинство из них отпадает из-за того что в адресах сервера используется протокол http/https а у меня используется wss. На текущий момент моя последняя попытка взята отсюда и тоже запрос не шлется:

val wsFactory = WebSocketFactory()
                .createSocket("wss://server/")
                .addHeader("token", context!!.getSharedPreferences("app_data", 0).getString("access_token", "")!!)

Либо я что-то не могу понять в принципах создания чата. До этого я работал с retrofit и возможно я жду обычного запрос-ответ поведения. Но судя по тому что я читаю, то здесь тоже приблизительно так все реализовано. Была так же такая попытка:

private fun instantiateWebSocket() {
        val client = OkHttpClient()
        val request: Request = Request.Builder()
                .url("wss://server/")
                .addHeader("token", context!!.getSharedPreferences("app_data", 0).getString("access_token", "")!!)
                .build()


        Timber.i(request.toString())

        val socketListener = SocketListener(context!!)
        webSocket = client.newWebSocket(request, socketListener)
        webSocket!!.send("0909")

    }

    class SocketListener(cont: Context) : WebSocketListener() {
        var context: Context = cont
        override fun onOpen(webSocket: WebSocket, response: Response) {
            Timber.i(response.toString())
            Runnable { Toast.makeText(context, "Connection Established!", Toast.LENGTH_LONG).show() }
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            val jsonObject = JSONObject()
            try {
                jsonObject.put("message", text)
                jsonObject.put("byServer", true)
            } catch (e: JSONException) {
                e.printStackTrace()
            }

        }

        init {
            this.context = cont
        }
    }

и тут запрос тоже не шлется. Что я не так делаю? Может у кого-то был опыт создания чата и есть рабочий способ?
Ответ:
Данный ответ пишу для таких же как и я - тех кто ничего не знает про сокеты и как писать чат. Я потратил немного времени на исследование и в итоге у меня получилось реализовать то что нужно. Для создания чата я использовал OkHttp. Для начала создадим клиент:

 val client = OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build()

дальше формируем запрос:

val request = Request.Builder()
                .url(Constants.TEST_CHAT_URL)
                .build()

и наконец создаем сокет:

webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                super.onClosed(webSocket, code, reason)
                Timber.i("closing data: $code -> $reason")
            }

            override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                super.onClosing(webSocket, code, reason)
                webSocket.close(1000, null)
                Timber.i("Closing : $code / $reason")
            }

            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                super.onFailure(webSocket, t, response)
                Timber.i("Error: %s", t.localizedMessage)
            }

            override fun onMessage(webSocket: WebSocket, text: String) {
                super.onMessage(webSocket, text)
                Timber.i("Receiving : $text")

            }

            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                super.onMessage(webSocket, bytes)
                Timber.i("Receiving bytes : %s", bytes.hex())
            }

            override fun onOpen(webSocket: WebSocket, response: Response) {
                super.onOpen(webSocket, response)
                Timber.i("on open")
            }
        })

После того как пообщались с человеком, нужно закрыть соединение:

webSocket.close(1000, null)

Для отправки сообщения нужно использовать функцию send:

webSocket.send("some_string")

Вот и все :) Оказалось не так сложно как казалось вначале. Возможно у кого-то будут замечания/предложения - выслушаю с удовольствием.



Report Page