Kit SDK de messagerie client Chat IVS : coroutines Kotlin, partie 1 : salles de chat
Il s'agit de la première partie d'un didacticiel en deux volets. Vous apprendrez les bases de l'utilisation du SDK de messagerie du Chat Amazon IVS en créant une application Android entièrement fonctionnelle à l'aide du langage de programmation Kotlin
Avant de commencer le module, prenez quelques minutes pour vous familiariser avec les prérequis, les concepts clés des jetons de discussion et le serveur principal nécessaire à la création de salles de chat.
Ces didacticiels sont conçus pour les développeurs Android expérimentés qui découvrent le SDK de messagerie d'IVS Chat. Vous devrez être à l'aise avec le langage de programmation Kotlin et la création d'interfaces utilisateur sur la plateforme Android.
Cette première partie du didacticiel est divisée en plusieurs sections :
Pour une documentation complète sur le SDK, commencez par le SDK de messagerie client Chat Amazon IVS (ici dans le Guide de l'utilisateur Chat Amazon IVS) et la Messagerie client de chat : référence du SDK pour Android
Prérequis
-
Familiarisez-vous avec Kotlin et la création d'applications sur la plateforme Android. Si vous n'êtes pas familiarisé avec la création d'applications pour Android, découvrez les bases dans le guide Créer votre première application
pour les développeurs Android. -
Lisez et assurez-vous d'avoir compris Mise en route avec le chat Amazon IVS.
-
Créez un utilisateur AWS IAM avec les fonctionnalités
CreateChatToken
etCreateRoom
définies dans une politique IAM existante. (Consultez Mise en route avec le chat Amazon IVS.) -
Assurez-vous que les clés secrètes et d'accès de cet utilisateur sont stockées dans un fichier d'informations d'identification AWS. Pour obtenir des instructions, consultez le Guide de l'utilisateur de l'interface de ligne de commande AWS (en particulier les paramètres de configuration et de fichier d'informations d'identification).
-
Créez une salle de chat et enregistrez son ARN. Consultez Mise en route avec le chat Amazon IVS. (Si vous n'enregistrez pas l'ARN, vous pourrez le consulter ultérieurement à l'aide de la console ou de l'API Chat.)
Configurer un serveur d'authentification/d'autorisation local
Votre serveur backend est chargé à la fois de créer des salles de chat et de générer les jetons de chat nécessaires au SDK de chat IVS pour Android pour authentifier et autoriser vos clients à accéder à vos salles de chat.
Consultez la section Créer un jeton de chat dans Mise en route avec Chat Amazon IVS. Comme le montre l'organigramme, votre code côté serveur est chargée de créer un jeton de chat. Cela signifie que votre application doit fournir ses propres moyens de générer un jeton de chat en demandant un jeton à votre application côté serveur.
Nous utilisons l'infrastructure Ktor
À ce stade, nous nous attendons à ce que vos informations d'identification AWS soient correctement configurées. Pour savoir comment procéder, consultez Configuration des informations d'identification AWS temporaires et de la région AWS pour le développement.
Créez un nouveau répertoire et appelez-le chatterbox
et, à l'intérieur, un autre, appelé auth-server
.
La structure de notre serveur sera la suivante :
- auth-server - src - main - kotlin - com - chatterbox - authserver - Application.kt - resources - application.conf - logback.xml - build.gradle.kts
Remarque : vous pouvez directement copier/coller le code ici dans les fichiers référencés.
Ensuite, nous ajoutons toutes les dépendances et tous les plugins nécessaires au fonctionnement de notre serveur d'authentification :
Script Kotlin :
// ./auth-server/build.gradle.kts plugins { application kotlin("jvm") kotlin("plugin.serialization").version("1.7.10") } application { mainClass.set("io.ktor.server.netty.EngineMain") } dependencies { implementation("software.amazon.awssdk:ivschat:2.18.1") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20") implementation("io.ktor:ktor-server-core:2.1.3") implementation("io.ktor:ktor-server-netty:2.1.3") implementation("io.ktor:ktor-server-content-negotiation:2.1.3") implementation("io.ktor:ktor-serialization-kotlinx-json:2.1.3") implementation("ch.qos.logback:logback-classic:1.4.4") }
Nous devons maintenant configurer la fonctionnalité de journalisation pour le serveur d'authentification. (Pour plus d'informations, veuillez consulter Configure logger
XML :
// ./auth-server/src/main/resources/logback.xml <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="trace"> <appender-ref ref="STDOUT"/> </root> <logger name="org.eclipse.jetty" level="INFO"/> <logger name="io.netty" level="INFO"/> </configuration>
Le serveur Ktorapplication.*
du répertoire resources
. Nous les ajoutons donc également. (Pour plus d'informations, consultez Configuration in a file
HOCON :
// ./auth-server/src/main/resources/application.conf ktor { deployment { port = 3000 } application { modules = [ com.chatterbox.authserver.ApplicationKt.main ] } }
Enfin, implémentons notre serveur :
Kotlin :
// ./auth-server/src/main/kotlin/com/chatterbox/authserver/Application.kt package com.chatterbox.authserver import io.ktor.http.* import io.ktor.serialization.kotlinx.json.* import io.ktor.server.application.* import io.ktor.server.plugins.contentnegotiation.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import software.amazon.awssdk.services.ivschat.IvschatClient import software.amazon.awssdk.services.ivschat.model.CreateChatTokenRequest @Serializable data class ChatTokenParams(var userId: String, var roomIdentifier: String) @Serializable data class ChatToken( val token: String, val sessionExpirationTime: String, val tokenExpirationTime: String, ) fun Application.main() { install(ContentNegotiation) { json(Json) } routing { post("/create_chat_token") { val callParameters = call.receive<ChatTokenParams>() val request = CreateChatTokenRequest.builder().roomIdentifier(callParameters.roomIdentifier) .userId(callParameters.userId).build() val token = IvschatClient.create() .createChatToken(request) call.respond( ChatToken( token.token(), token.sessionExpirationTime().toString(), token.tokenExpirationTime().toString() ) ) } } }
Créer un projet Chatterbox
Pour créer un projet Android, installez et ouvrez Android Studio
Suivez les étapes répertoriées dans le guide officiel Android Créer un projet
-
Dans Choisir le type de projet
, choisissez le modèle de projet Empty Activity (Activité vide) pour notre application Chatterbox.
-
Dans Configurer votre projet
, choisissez les valeurs suivantes pour les champs de configuration : -
Nom : My App
-
Nom de package : com.chatterbox.myapp
-
Emplacement d'enregistrement : pointez sur le répertoire
chatterbox
créé à l'étape précédente -
Langage : Kotlin
-
Niveau d'API minimum : API 21 : Android 5.0 (Lollipop)
-
Après avoir correctement spécifié tous les paramètres de configuration, la structure de nos fichiers dans le dossier chatterbox
doit ressembler à ce qui suit :
- app - build.gradle ... - gradle - .gitignore - build.gradle - gradle.properties - gradlew - gradlew.bat - local.properties - settings.gradle - auth-server - src - main - kotlin - com - chatterbox - authserver - Application.kt - resources - application.conf - logback.xml - build.gradle.kts
Maintenant que nous avons un projet Android fonctionnel, nous pouvons ajouter com.amazonaws:ivs-chat-messagingbuild.gradle
. (Pour plus d'informations sur la boîte à outils de génération Gradle
Remarque : en haut de chaque extrait de code, il y a un chemin vers le fichier dans lequel vous devez apporter des modifications à votre projet. Le chemin est relatif par rapport à la racine du projet.
Kotlin :
// ./app/build.gradle plugins { // ... } android { // ... } dependencies { implementation 'com.amazonaws:ivs-chat-messaging:1.1.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' // ... }
Une fois la nouvelle dépendance ajoutée, exécutez Synchroniser le projet avec les fichiers Gradle dans Android Studio pour synchroniser le projet avec la nouvelle dépendance. (Pour de plus amples informations, veuillez consulter la section Ajouter des dépendances de build
Pour exécuter facilement notre serveur d'authentification (créé dans la section précédente) à partir de la racine du projet, nous l'incluons en tant que nouveau module dans settings.gradle
. (Pour plus d'informations, voir Structurer et construire un composant de logiciel avec Gradle
Script Kotlin :
// ./settings.gradle // ... rootProject.name = "My App" include ':app' include ':auth-server'
À présent, comme auth-server
est inclus dans le projet Android, vous pouvez exécuter le serveur d'authentification à l'aide de la commande suivante depuis la racine du projet :
Shell :
./gradlew :auth-server:run
Se connecter à une salle de chat et observer les mises à jour de la connexion
Pour ouvrir une connexion à une salle de chat, nous utilisons le rappel du cycle de vie de l'activité onCreate()region
et tokenProvider
pour lancer une connexion à une salle.
Remarque : la fonction fetchChatToken
présentée dans l'extrait ci-dessous sera implémentée dans la section suivante.
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt package com.chatterbox.myapp // ... // AWS region of the room that was created in Getting Started with Amazon IVS Chat const val REGION = "us-west-2" class MainActivity : AppCompatActivity() { private var room: ChatRoom? = null // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create room instance room = ChatRoom(REGION, ::fetchChatToken) } // ... }
L'affichage et la réaction aux modifications de la connexion à une salle de chat est un élément essentiel pour la création d'une application de chat comme chatterbox
. Avant de pouvoir commencer à interagir avec la salle, nous devons nous abonner aux événements relatifs à l'état de connexion de la salle de chat pour obtenir des mises à jour.
Dans le SDK Chat pour la coroutine, ChatRoom
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt package com.chatterbox.myapp // ... const val TAG = "Chatterbox-MyApp" class MainActivity : AppCompatActivity() { // ... override fun onCreate(savedInstanceState: Bundle?) { // ... // Create room instance room = ChatRoom(REGION, ::fetchChatToken).apply { lifecycleScope.launch { stateChanges().collect { state -> Log.d(TAG, "state change to $state") } } lifecycleScope.launch { receivedMessages().collect { message -> Log.d(TAG, "messageReceived $message") } } lifecycleScope.launch { receivedEvents().collect { event -> Log.d(TAG, "eventReceived $event") } } lifecycleScope.launch { deletedMessages().collect { event -> Log.d(TAG, "messageDeleted $event") } } lifecycleScope.launch { disconnectedUsers().collect { event -> Log.d(TAG, "userDisconnected $event") } } } } }
Ensuite, nous devons fournir la possibilité de lire l'état de la connexion à la salle. Nous le conserverons dans la propriétéMainActivity.kt
et l'initialiserons à l'état DÉCONNECTÉ par défaut pour les salles (voir ChatRoom
state
dans la référence du SDK IVS Chat pour AndroidupdateConnectionState
:
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt package com.chatterbox.myapp // ... class MainActivity : AppCompatActivity() { private var connectionState = ChatRoom.State.DISCONNECTED // ... private fun updateConnectionState(state: ChatRoom.State) { connectionState = state when (state) { ChatRoom.State.CONNECTED -> { Log.d(TAG, "room connected") } ChatRoom.State.DISCONNECTED -> { Log.d(TAG, "room disconnected") } ChatRoom.State.CONNECTING -> { Log.d(TAG, "room connecting") } } }
Ensuite, nous intégrons notre fonction de mise à jour de l'état à la propriété Chatroom.Listener
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt package com.chatterbox.myapp // ... class MainActivity : AppCompatActivity() { // ... override fun onCreate(savedInstanceState: Bundle?) { // ... // Create room instance room = ChatRoom(REGION, ::fetchChatToken).apply { lifecycleScope.launch { stateChanges().collect { state -> Log.d(TAG, "state change to $state") updateConnectionState(state) } } // ... } } }
Maintenant que nous sommes en mesure d'enregistrer, d'écouter et de réagir aux mises à jour d'état de ChatRoom
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt package com.chatterbox.myapp // ... class MainActivity : AppCompatActivity() { // ... private fun connect() { try { room?.connect() } catch (ex: Exception) { Log.e(TAG, "Error while calling connect()", ex) } } // ... }
Créer un fournisseur de jetons
Il est temps de créer une fonction chargée de créer et de gérer des jetons de chat dans notre application. Dans cet exemple, nous utilisons le client HTTP Retrofit pour Android
Avant de pouvoir envoyer du trafic réseau, nous devons configurer une configuration de sécurité réseau pour Android. Pour plus d'informations, consultez Network security configurationuser-permission
et l'attribut networkSecurityConfig
ajoutés, qui indiqueront notre nouvelle configuration de sécurité réseau. Dans le code ci-dessous, remplacez <version>
par le numéro de version actuel du SDK de chat pour Android (par exemple, 1.1.0).
XML :
// ./app/src/main/AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.chatterbox.myapp"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:fullBackupContent="@xml/backup_rules" android:label="@string/app_name" android:networkSecurityConfig="@xml/network_security_config" // ... // ./app/build.gradle dependencies { implementation("com.amazonaws:ivs-chat-messaging:<version>") // ... implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") }
Déclarez votre adresse IP locale, par exemple 10.0.2.2
et les domaines localhost
comme fiables, pour commencer à échanger des messages avec notre backend :
XML :
// ./app/src/main/res/xml/network_security_config.xml <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">10.0.2.2</domain> <domain includeSubdomains="true">localhost</domain> </domain-config> </network-security-config>
Ensuite, nous devons ajouter une nouvelle dépendance, ainsi que l'ajout d'un convertisseur Gson<version>
par le numéro de version actuel du SDK de chat pour Android (par exemple, 1.1.0).
Script Kotlin :
// ./app/build.gradle dependencies { implementation("com.amazonaws:ivs-chat-messaging:<version>") // ... implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") }
Pour récupérer un jeton de chat, nous devons effectuer une requête HTTP POST depuis notre application chatterbox
. Nous définissons la demande dans une interface que Retrofit doit implémenter. (Voir la documentation de Retrofit
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/network/ApiService.kt package com.chatterbox.myapp.network import com.amazonaws.ivs.chat.messaging.ChatToken import retrofit2.Call import retrofit2.http.Body import retrofit2.http.POST data class CreateTokenParams(var userId: String, var roomIdentifier: String) interface ApiService { @POST("create_chat_token") fun createChatToken(@Body params: CreateTokenParams): Call<ChatToken> } // ./app/src/main/java/com/chatterbox/myapp/network/RetrofitFactory.kt package com.chatterbox.myapp.network import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory object RetrofitFactory { private const val BASE_URL = "http://10.0.2.2:3000" fun makeRetrofitService(): ApiService { return Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build().create(ApiService::class.java) } }
Maintenant que le réseau est configuré, il est temps d'ajouter une fonction chargée de créer et de gérer notre jeton de chat. Nous l'ajoutons à MainActivity.kt
, qui a été automatiquement créé lors de la génération du projet :
Kotlin :
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt package com.chatterbox.myapp import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch import com.amazonaws.ivs.chat.messaging.* import com.amazonaws.ivs.chat.messaging.coroutines.* import com.chatterbox.myapp.network.CreateTokenParams import com.chatterbox.myapp.network.RetrofitFactory import retrofit2.Call import java.io.IOException import retrofit2.Callback import retrofit2.Response // custom tag for logging purposes const val TAG = "Chatterbox-MyApp" // any ID to be associated with auth token const val USER_ID = "test user id" // ID of the room the app wants to access. Must be an ARN. See Amazon Resource Names(ARNs) const val ROOM_ID = "arn:aws:..." // AWS region of the room that was created in Getting Started with Amazon IVS Chat const val REGION = "us-west-2" class MainActivity : AppCompatActivity() { private val service = RetrofitFactory.makeRetrofitService() private var userId: String = USER_ID // ... private fun fetchChatToken(callback: ChatTokenCallback) { val params = CreateTokenParams(userId, ROOM_ID) service.createChatToken(params).enqueue(object : Callback<ChatToken> { override fun onResponse(call: Call<ChatToken>, response: Response<ChatToken>) { val token = response.body() if (token == null) { Log.e(TAG, "Received empty token response") callback.onFailure(IOException("Empty token response")) return } Log.d(TAG, "Received token response $token") callback.onSuccess(token) } override fun onFailure(call: Call<ChatToken>, throwable: Throwable) { Log.e(TAG, "Failed to fetch token", throwable) callback.onFailure(throwable) } }) } }
Étapes suivantes
Maintenant que vous avez établi une connexion à la salle de chat, passez à la seconde partie de ce didacticiel Coroutines Kotlin, Messages et événements.