Написание чата 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")
Вот и все :) Оказалось не так сложно как казалось вначале. Возможно у кого-то будут замечания/предложения - выслушаю с удовольствием.