Android studio socket kotlin

Integrating Sockets in Kotlin

Ever wondered how popular apps like Cricbuzz, Whatsapp, Trello, Google Docs work, or thought of building an app that gets automatic live data like a chatting app, a multiplayer game, a live quiz, etc? Then Socket.IO is the answer for you. In this article, I will illustrate how you can implement Socket.IO in your android app.

Socket.IO is a library that enables real-time, bidirectional, and event-based communication between the client and the server.

Socket.IO is built on top of the WebSockets API (Client-side) and NodeJs. But it is not an implementation of web sockets. It is used only for transport. Here both servers and clients can emit and listen to their calls. The server can also trigger the event on a specific route which is listened by their subscribers, which means the client has put their listener for particular events.

Kotlin doesn’t have its official documentation for Socket.IO so we will be studying its operation from Java documentation and will translate it to Kotlin as both languages are interoperable.

There are two methods by which you can implement Socket.IO in your native android app.

The library provided by Naoyuki Kanezawa has also published its blog for Socket.IO using java in android. I would recommend you to use this library as it is easy to implement, provides socket (connect, disconnect, reconnect) detection, auto-reconnect feature, and is also promoted in official Socket.IO documentation

Now let’s move to the coding part and in the next few steps, you can set up your socket.io connection. ✌️

Startup‍🚀

• First and foremost add the dependency to app-level build.gradle file.

• Don’t forget to add internet permission in the manifest file. 😅

Socket Initialization😎

• Create a Kotlin class for socket initialization which can be used anywhere in the project. Here IO.socket() method returns a socket for https://yourSocketURL.com with the default options. Notice that the method mSocket caches the result, so you can always get the same Socket instance for an URL from any Activity or Fragment.

• Don’t forget to add your socket initialization application class name in the manifest file. 😅

Socket Connection to the Server😃

• Now we will create the object of the Socket Instance class which we created earlier and connect the socket using .connect() method. We will use IO.options() method so that socket will be reconnected by itself if ever It gets disconnected due to some network problem.

• To check if the socket is connected or not we can use .connected() method.

Emit and Listen Events😊

• For receiving instant real-time data we need to use on() method. We can get data in a JSON data block or any other data form. To show anything on the screen all the UI bind logic should be coded on the UI Thread part as the socket works on the background thread.

• Checking when the socket is disconnected or reconnected.

• For sending data to the server in the form of JSON data block or any other data form we have to use the emit() method.

If you are going to receive data based on what you emit to the server then first you should start listening to the event using the on() method and then emit your data.

• And last but not the least, don’t forget to close the socket connection using .disconnect() method and remove the listener using .off() method when you are done.😇

Читайте также:  Режим чтения андроид что это

Let me know in the comments if you have any issues and topics you would be interested in learning more about. You can also reach out to me on Twitter and Instagram.

DSC KIET

Student community of developers driven by the urge to learn and contribute

Источник

Работа с сетью в Android с использованием корутин и Retrofit

Чем больше я читал и смотрел доклады про корутины в Kotlin, тем больше я восхищался этим средством языка. Недавно в Kotlin 1.3 вышел их стабильный релиз, а значит, настало время начать погружение и опробовать корутины в действии на примере моего существующего RxJava-кода. В этом посте мы сфокусируемся на том, как взять существующие запросы к сети и преобразовать их, заменив RxJava на корутины.

Откровенно говоря, перед тем как я попробовал корутины, я думал, что они сильно отличаются от того, что было раньше. Однако, основной принцип корутин включает те же понятия, к которым мы привыкли в реактивных потоках RxJava. Для примера давайте возьмем простую конфигурацию RxJava для создания запроса к сети из одного моего приложения:

  • Определяем сетевой интерфейс для Ретрофита, используя Rx-адаптер (retrofit2:adapter-rxjava2). Функции будут возвращать объекты из Rx-фреймворка, такие как Single или Observable. (Здесь и далее используются функции, а не методы, так как предполагается, что старый код был также написан на Kotlin. Ну или сконвертирован из Java через Android Studio).
  • Вызываем определенную функцию из другого класса (например репозитория, или активити).
  • Определяем для потоков, на каком Scheduler-е они будут выполняться и возвращать результат (методы .subscribeOn() и .observeOn()).
  • Сохраняем ссылку на объект для отписки (например в CompositeObservable).
  • Подписываемся на поток эвентов.
  • Отписываемся от потока в зависимости от событий жизненного цикла Activity.

Это основной алгоритм работы с Rx (не учитывая функции маппинга и детали других манипуляций с данными). Что касается корутин – принцип сильно не меняется. Та же концепция, меняется только терминология.

  • Определяем сетевой интерфейс для Ретрофита, используя адаптер для корутин. Функции будут возвращать Deferred объекты из API корутин.
  • Вызываем эти функции из другого класса (например репозитория, или активити). Единственное отличие: каждая функция должна быть помечен как отложенная (suspend).
  • Определяем dispatcher, который будет использован для корутина.
  • Сохраняем ссылку на Job-объект для отписки.
  • Запускаем корутин любым доступным способом.
  • Отменяем корутины в зависимости от событий жизненного цикла Activity.

Как можно заметить из приведенных выше последовательностей, процесс выполнения Rx и корутин очень похож. Если не учитывать детали реализации, это означает, что мы можем сохранить подход, который у нас есть – мы только заменяем некоторые вещи, чтобы сделать нашу реализацию coroutine-friendly.

Первый шаг, который мы должны сделать – позволить Ретрофиту возвращать Deferred-объекты. Объекты типа Deferred представляют собой неблокирующие future, которые могут быть отменены, если нужно. Эти объекты по сути представляют собой корутинную Job, которая содержит значение для соответствующей работы. Использование Deferred типа позволяет нам смешать ту же идею, что и Job, с добавлением возможности получить дополнительные состояния, такие как success или failure – что делает его идеальным для запросов к сети.

Если вы используете Ретрофит с RxJava, вероятно, вы используете RxJava Call Adapter Factory. К счастью, Джейк Вортон написал её эквивалент для корутин.

Мы можем использовать этот call adapter в билдере Ретрофита, и затем имплементировать наш Ретрофит-интерфейс так же, как было с RxJava:

Теперь посмотрим на интерфейс MyService, который использован выше. Мы должны заменить в Ретрофит-интерфейсе возвращаемые Observable-типы на Deferred. Если раньше было так:

То теперь заменяем на:

Каждый раз, когда мы вызовем getData() – нам вернется объект Deferred – аналог Job для запросов к сети. Раньше мы как-то так вызывали эту функцию с RxJava:

В этом RxJava потоке мы вызываем нашу служебную функцию, затем применяем map-операцию из RxJava API с последующим маппингом данных, вернувшихся из запроса, в что-то, используемое в UI слое. Это немного поменяется, когда мы используем реализацию с корутинами. Для начала, наша функция должна быть suspend (отложенной), для того, чтобы сделать ленивую операцию внутри тела функции. И для этого вызывающая функция должна быть также отложенной. Отложенная функция – неблокирующая, и ею можно управлять после того, как она будет первоначально вызвана. Можно ее стартануть, поставить на паузу, возобновить или отменить.

Читайте также:  Android не отображается имя звонящего

Теперь мы должны вызвать нашу служебную функцию. На первый взгляд, мы выполняем то же самое, но нужно помнить, что теперь мы получаем Deferred вместо Observable.

Из-за этого изменения мы не можем больше использовать цепочку map-операция из RxJava API. И даже в этой точке нам не доступны данные – мы только имеем Deferred-инстанс. Теперь мы должны использовать функцию await() для того, чтобы дождаться результата выполнения запроса и затем продолжить выполнение кода внутри функции:

В этой точке мы получаем завершенный запрос и данные из него, доступные для использования. Поэтому мы можем теперь совершать операции маппинга:

Мы взяли наш Ретрофит-интерфейс вместе с вызывающим классом и использовали корутины. Теперь же мы хотим вызвать этот код из наших Activity или фрагментов и использовать данные, которые мы достали из сети.

В нашей Activity начнем с создания ссылки на Job, в которую мы сможем присвоить нашу корутинную операцию и затем использовать для управления, например отмены запроса, во время вызова onDestroy().

Теперь мы можем присвоить что-то в переменную myJob. Давайте посмотрим на наш запрос с корутинами:

В этом посте я не хотел бы углубляться в Dispatchers или исполнение операций внутри корутинов, так как это тема для других постов. Вкратце, что здесь происходит:

  • Создаем инстанс CoroutineScope, используя IO Dispatcher в качестве параметра. Этот диспатчер используется для совершения блокирующих операций ввода-вывода, таких как сетевые запросы.
  • Запускаем наш корутин функцией launch – эта функция запускает новый корутин и возвращает ссылку в переменную типа Job.
  • Затем мы используем ссылку на наш репозиторий для получения данных, выполняя сетевой запрос.
  • В конце мы используем Main диспатчер для совершения работы на UI-потоке. Тут мы сможем показать полученные данные пользователям.

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

В этом посте мы заменили RxJava-реализацию ответов Ретрофита на Deferred объекты из API корутин. Мы вызываем эти функции для получения данных из сети, и затем отображем их в нашем активити. Надеюсь, вы увидели, как мало изменений нужно сделать, чтобы начать работать с корутинами, и оценили простоту API, особенно в процессе чтения и написания кода.

В комментариях к оригинальному посту я нашел традиционную просьбу: покажите код целиком. Поэтому я сделал простое приложение, которое при старте получает расписание электричек с API Яндекс.Расписаний и отображает в RecyclerView. Ссылка: https://github.com/AndreySBer/RetrofitCoroutinesExample

Еще хотелось бы добавить, что корутины кажутся неполноценной заменой RxJava, так как не предлагают равноценного набора операций для синхронизации потоков. В этой связи стоит посмотреть на реализацию ReactiveX для Kotlin: RxKotlin.

Источник

Kotlin tcp with java sockets 🧦

We will be using the default java sockets to create a tcp server/client with Kotlin:

If you already know it in Java then no surprise, but since you might be interested in Ktor or the kotlin syntax:

You can have access to the source code at sylhare/tcp.

Implementation

So I will put only snippets of the most simple relevant parts here. You can always check the source code later with much more example, tests and so on!

Server and Client

There are two concepts here:

  • A server accepts clients connection.
  • A Client looks for a server to establish a connection.

However once the connection is established ie the client socket is created and connected to the server. Then bytes exchange can flow.

Socket

The Socket is that connection between the server and the client. A Socket has an input and a output. Depending on where you look at it, it does not mean the same thing because it is a bidirectional link.

  • A Server’s input is the client’s output.
  • A Server’s output is the client’s input.

So basically you read from the input and write to the output. You work with Bytes, which might not be the best for your use case. For text, you can use some wrapper:

  • To write and send text:
Читайте также:  Android emulator location android studio

The write is pretty straightforward, you can flush the outputStream meaning to forcefully send whatever is in the pipe at that moment. The reader requires a buffer, which it will use to copy the read bytes into it.

Multi bind

To create one server that will be able to have binds with multiple clients. A bind is the same as a socket connection.

Oracle documentation about TCP Client Server sum it up quite well:

This infinite loop will be on stand by and wait for a socket connection at server.accept() . The handleClient will use the socket to exchange data with the client.

Put it all together

Client

Let’s create a simple client that will send a message to a server:

Server

Now we create a server that will respond to the received message. This is usually call an echo server.

Output

Let’s run both at the same time to see the client’s log:

We need to start the server in a Thread so that the client will run too. We send only one message then the program stops:

The client receives its response from the server. As you may see a server and a client are not very different.

To make the server multi bind you would just need to put everything, but the first line in an infinite loop.

Testing

For testing a connection and your tcp server, client. You have a wide range of possibilities.

With real traffic

In order to test your client or server, you will need a server, or a client in order to build a socket connexion, there’s no magic. In simple project you might think that your test code looks similar as your main code. But as you develop new features, the test client / server should remain simple.

You will need to run the server on a different thread!

Since you want the server to accept new connexion, you’ll want to have it running on a different thread so that the tests can move on. A very simple example could be if you had a Server object using what was shown before:

The you can create your test with your client:

You create your Client object that would look like what was shown above. Connect it to the server running in the thread, send something and assuming that sendMessage methods return the received response, you can assert on it.

That’s a very simple use case, you might not want to return the response from the sendMessage and depending on if you’re testing the client, or the server you may go different ways to test the expected behaviour. Like creating having a TestServer or a testClient that will have some special assertReceived method for what you need to test.

With Mock

You could mock the socket, but it can quickly get tedious, and you’d be better off with a real socket client / server for your tests. But you may want to use mock for corner cases or to decouple your client tests from your business logic tests.

Here if you’d like to simulate an Exception. You would do that using mockK in kotlin:

The relaxed mock is used, so you don’t have to manually specify and mock all the internals. Mockk will do it for you. Obviously this test is just a dummy example, you don’t want to let uncaught exceptions in your code.

Post Scriptum

I updated this article seeing someone had trouble following it and opened a question on stackoverflow. So I answer and updated this article 😃

If you want to be a truly majestic person, you can always go ⬆ upvote the answer. You nice lovely papayas 🧡

Источник

Оцените статью