

# Client-Messaging-SDK für IVS Chat: Tutorial für Kotlin-Coroutines, Teil 1: Chaträume
<a name="chat-sdk-kotlin-tutorial-chat-rooms"></a>

Hierbei handelt es sich um den ersten Teil eines zweiteiligen Tutorials. Sie werden die Grundlagen der Arbeit mit dem SDK für Amazon IVS Chat Messaging kennenlernen, indem Sie eine voll funktionsfähige Android-Anwendung mithilfe der [Kotlin](https://kotlinlang.org/)-Programmiersprache und [Coroutines](https://kotlinlang.org/docs/coroutines-overview.html) entwickeln. Wir nennen die App *Chatterbox*.

Bevor Sie das Modul starten, nehmen Sie sich ein paar Minuten Zeit, um sich mit den Voraussetzungen, den wichtigsten Konzepten hinter Chat-Token und dem Backend-Server vertraut zu machen, der für die Erstellung von Chaträumen erforderlich ist.

Diese Tutorials sind für erfahrene Android-Entwickler gedacht, die das IVS Chat Messaging SDK noch nicht kennen. Sie müssen mit der Programmiersprache Kotlin und der Erstellung von Benutzeroberflächen auf der Android-Plattform vertraut sein.

Der vorliegende erste Teil des Tutorials ist in mehrere Abschnitte unterteilt:

1. [Einrichten eines lokalen Authentifizierungs-/Autorisierungsservers](#chat-kotlin-rooms-auth-server)

1. [Erstellen eines Chatterbox-Projekts](#chat-kotlin-rooms-chatterbox)

1. [Mit einem Chatraum verbinden und Verbindungsupdates beobachten](#chat-kotlin-rooms-connect)

1. [Erstellen eines Token-Anbieters](#chat-kotlin-rooms-token-provider)

1. [Nächste Schritte](#chat-kotlin-rooms-next-steps)

Umfassende Informationen zum SDK finden Sie im [Client-Messaging-SDK für Amazon IVS Chat](chat-sdk.md) (im vorliegenden *Benutzerhandbuch zu Amazon IVS Chat*) und unter [Chat Client Messaging: SDK für Android-Referenz](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/latest/) auf GitHub.

## Voraussetzungen
<a name="chat-kotlin-rooms-prerequisites"></a>
+ Sie sind vertraut mit Kotlin und der Erstellung von Anwendungen auf der Android-Plattform. Wenn Sie mit der Erstellung von Anwendungen für Android nicht vertraut sind, können Sie die Grundlagen im Leitfaden [Erstellen Ihrer ersten App](https://developer.android.com/codelabs/basic-android-kotlin-compose-first-app#0) für Android-Entwickler erlernen.
+ Lesen Sie sich [Erste Schritte mit Amazon IVS Chat](getting-started-chat.md) durch.
+ Erstellen Sie einen AWS-IAM-Benutzer mit den Fähigkeiten `CreateChatToken` und `CreateRoom`, die in einer vorhandenen IAM-Richtlinie definiert sind. (Siehe ). [Erste Schritte mit Amazon IVS Chat](getting-started-chat.md).)
+ Stellen Sie sicher, dass die Geheim-/Zugriffsschlüssel für diesen Benutzer in einer Datei mit den AWS-Anmeldeinformationen gespeichert sind. Entsprechende Anweisungen finden Sie im [Benutzerhandbuch zur AWS-CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) (insbesondere unter [Einstellungen für Konfigurations- und Anmeldeinformationsdateien](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)).
+ Erstellen Sie einen Chatroom und speichern Sie dessen ARN. Siehe [Erste Schritte mit Amazon IVS Chat](getting-started-chat.md). (Wenn Sie den ARN nicht speichern, können Sie ihn später über die Konsole oder die Chat-API nachschlagen.)

## Einrichten eines lokalen Authentifizierungs-/Autorisierungsservers
<a name="chat-kotlin-rooms-auth-server"></a>

Ihr Backend-Server ist sowohl für die Erstellung von Chaträumen als auch für die Generierung der Chat-Token verantwortlich, die das SDK von IVS Chat Android für die Authentifizierung und Autorisierung Ihrer Kunden in Ihren Chaträumen benötigt.

Weitere Informationen finden Sie unter [Erstellen eines Chat-Tokens](getting-started-chat-auth.md) unter *Erste Schritte mit Amazon IVS Chat*. Wie im dortigen Flussdiagramm gezeigt, erfolgt die Erstellung eines Chat-Tokens in Ihrem serverseitigen Code. Das bedeutet, dass Ihre App eigene Mittel zur Generierung eines Chat-Tokens bereitstellen muss, indem sie ein Token von der serverseitigen Anwendung anfordert.

Mit dem [Ktor](https://ktor.io/)-Framework erstellen wir einen lokalen Live-Server, der die Erstellung von Chat-Token mithilfe Ihrer lokalen AWS-Umgebung verwaltet. 

Zu diesem Zeitpunkt gehen wir davon aus, dass Sie Ihre AWS-Anmeldeinformationen korrekt eingerichtet haben. Schritt-für-Schritt-Informationen dazu finden Sie unter [Einrichten der temporären AWS-Anmeldeinformationen und der AWS‑Region für die Entwicklung](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html).

Erstellen Sie ein neues Verzeichnis mit dem Namen `chatterbox` und darin ein weiteres Verzeichnis mit dem Namen `auth-server`*.*

Unser Server-Ordner hat die folgende Struktur:

```
- auth-server
  - src
    - main
      - kotlin
        - com
          - chatterbox
            - authserver
              - Application.kt
       - resources
         - application.conf
         - logback.xml
   - build.gradle.kts
```

*Hinweis: Sie können den Code hier direkt in die referenzierten Dateien kopieren/einfügen.*

Als Nächstes fügen wir alle notwendigen Abhängigkeiten und Plugins hinzu, damit unser Authentifizierungsserver funktioniert:

**Kotlin-Skript:**

```
// ./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")
}
```

Jetzt müssen wir die Protokollierungsfunktion für den Authentifizierungsserver einrichten. (Weitere Informationen finden Sie unter [Logger konfigurieren](https://ktor.io/docs/logging.html#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>
```

Der [Ktor](https://ktor.io/docs/welcome.html)-Server benötigt Konfigurationseinstellungen, die er automatisch aus der `application.*`-Datei im `resources`-Verzeichnis lädt, also fügen wir diese ebenfalls hinzu. (Weitere Informationen finden Sie unter [Konfigurierung in einer Datei](https://ktor.io/docs/configurations.html#configuration-file).)

**HOCON:**

```
// ./auth-server/src/main/resources/application.conf

ktor {
   deployment {
      port = 3000
   }
   application {
      modules = [ com.chatterbox.authserver.ApplicationKt.main ]
   }
}
```

Lassen Sie uns abschließend unseren Server implementieren:

**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()
            )
         )
      }
   }
}
```

## Erstellen eines Chatterbox-Projekts
<a name="chat-kotlin-rooms-chatterbox"></a>

Um ein Android-Projekt zu erstellen, installieren und öffnen Sie [Android Studio](https://developer.android.com/studio).

Folgen Sie den Schritten, die in der offiziellen [Android-Anleitung zum Erstellen eines Projekts](https://developer.android.com/studio/projects/create-project) aufgeführt sind. 
+ Wählen Sie unter [Projekt auswählen](https://developer.android.com/studio/projects/create-project) die Projektvorlage **Leere Aktivität** für unsere Chatterbox-App aus.
+ Wählen Sie unter [Projekt konfigurieren](https://developer.android.com/studio/projects/create-project#configure) die folgenden Werte für Konfigurationsfelder aus:
  + **Name**: My App
  + **Paketname**: com.chatterbox.myapp
  + **Speicherort**: Zeigt auf das im vorherigen Schritt erstellte `chatterbox`-Verzeichnis
  + **Sprache**: Kotlin
  + **API-Mindestlevel**: API 21: Android 5.0 (Lollipop)

Nachdem Sie alle Konfigurationsparameter korrekt angegeben haben, sollte unsere Dateistruktur im `chatterbox`-Ordner wie folgt aussehen:

```
- 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
```

Jetzt, da wir ein funktionierendes Android-Projekt haben, können wir [com.amazonaws:ivs-chat-messaging](https://mvnrepository.com/artifact/com.amazonaws/ivs-chat-messaging) und [org.jetbrains.kotlinx:kotlinx-coroutines-core](https://github.com/Kotlin/kotlinx.coroutines) zu unseren `build.gradle`-Abhängigkeiten hinzufügen. (Weitere Informationen zum [Gradle](https://gradle.org/)-Build-Toolkit finden Sie unter [Ihren eigenen Build konfigurieren](https://developer.android.com/build).) 

**Hinweis:** Am Anfang jedes Codeausschnitts befindet sich ein Pfad zu der Datei, in der Sie Änderungen an Ihrem Projekt vornehmen sollten. Der Pfad ist relativ zur Root des Projekts.

**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'

// ...
}
```

Nachdem die neue Abhängigkeit hinzugefügt wurde, führen Sie **Projekt mit Gradle-Dateien synchronisieren** in Android Studio aus, um das Projekt mit der neuen Abhängigkeit zu synchronisieren. (Weitere Informationen finden Sie unter [Build-Abhängigkeiten hinzufügen](https://developer.android.com/build/dependencies).)

Um unseren Authentifizierungsserver (der im vorherigen Abschnitt erstellt wurde) bequem vom Projektstammverzeichnis aus ausführen zu können, fügen wir ihn als neues Modul in `settings.gradle` hinzu. (Weitere Informationen finden Sie unter [Strukturierung und Aufbau einer Softwarekomponente mit Gradle](https://docs.gradle.org/current/userguide/multi_project_builds.html).)

**Kotlin-Skript:**

```
// ./settings.gradle

// ...

rootProject.name = "My App"
include ':app'
include ':auth-server'
```

Von nun an, da `auth-server` im Android-Projekt enthalten ist, können Sie den Authentifizierungsserver mit dem folgenden Befehl aus dem Stammverzeichnis des Projekts starten:

**Shell:**

```
./gradlew :auth-server:run         
```

## Mit einem Chatraum verbinden und Verbindungsupdates beobachten
<a name="chat-kotlin-rooms-connect"></a>

Um eine Chatraum-Verbindung zu öffnen, verwenden wir [onCreate() activity lifecycle callback](https://developer.android.com/guide/components/activities/activity-lifecycle), welcher ausgelöst wird, wenn die Aktivität zum ersten Mal erstellt wird. Für den [ChatRoom-Constructor](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html) müssen wir `region` und `tokenProvider` bereitstellen, um eine Raumverbindung zu instanziieren.

**Hinweis:** Die `fetchChatToken`-Funktion im folgenden Ausschnitt wird im [nächsten Abschnitt](#chat-kotlin-rooms-token-provider) implementiert.

**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)
   }

// ...
}
```

Das Anzeigen und Reagieren auf Änderungen in der Verbindung eines Chatraums sind wesentliche Bestandteile einer Chat-App wie `chatterbox`. Bevor wir anfangen können, mit dem Raum zu interagieren, müssen wir die Verbindungsstatus-Ereignisse des Chat-Raums abonnieren, um Aktualisierungen zu erhalten.

[https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html) erwartet im Chat-SDK für Coroutine, dass wir die Lebenszyklusereignisse von Räumen in [Flow](https://kotlinlang.org/docs/flow.html) behandeln. Für den Moment protokollieren Funktionen nur Bestätigungsnachrichten, wenn diese aufgerufen werden:

**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")
                }
            }
        }
    }
}
```

Danach müssen wir die Möglichkeit bieten, den Raum-Verbindungsstatus zu lesen. Wir behalten sie in der `MainActivity.kt`-[Eigenschaft](https://kotlinlang.org/docs/properties.html) bei und initialisieren sie auf den Standardzustand DISCONNECTED für Räume (siehe `ChatRoom` `state` in der [IVS-Chat-Android-SDK-Referenz](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/latest/)). Um den lokalen Status auf dem neuesten Stand zu halten, müssen wir eine Statusaktualisierungsfunktion implementieren; nennen wir sie `updateConnectionState`:

**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")
          }
      }
}
```

Als Nächstes integrieren wir unsere Statusaktualisierungsfunktion in die Eigenschaft [ChatRoom.listener](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/listener.html):

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

                }
            }

      // ...

      }
   }
}
```

Da wir nun die Möglichkeit haben, den [ChatRoom](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html)-Status zu speichern, abzuhören und auf Aktualisierungen zu reagieren, ist es an der Zeit, eine Verbindung zu initialisieren:

**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)
      }
   }

   // ...
}
```

## Erstellen eines Token-Anbieters
<a name="chat-kotlin-rooms-token-provider"></a>

Es ist an der Zeit, eine Funktion zu erstellen, die für die Erstellung und Verwaltung von Chat-Token in unserer Anwendung verantwortlich ist. In diesem Beispiel verwenden wir den [Retrofit-HTTP-Client für Android](https://square.github.io/retrofit/).

Bevor wir Netzwerkverkehr senden können, müssen wir eine Netzwerksicherheitskonfiguration für Android einrichten. (Weitere Informationen finden Sie unter [Konfiguration der Netzwerksicherheit](https://developer.android.com/privacy-and-security/security-config).) Wir beginnen mit dem Hinzufügen von Netzwerkberechtigungen zur [App-Manifest](https://developer.android.com/guide/topics/manifest/manifest-intro)-Datei. Beachten Sie das hinzugefügte Tag `user-permission` und das hinzugefügte Attribut `networkSecurityConfig`, die auf unsere neue Netzwerksicherheitskonfiguration verweisen. *Ersetzen Sie im folgenden Code *`<version>`* durch die aktuelle Versionsnummer des Chat Android SDKs (z. B. 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")
}
```

Deklarieren Sie Ihre lokale IP-Adresse, z. B. die Domains `10.0.2.2` und `localhost` als vertrauenswürdig, um mit dem Nachrichtenaustausch mit unserem Backend zu beginnen:

**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>
```

Als Nächstes müssen wir eine neue Abhängigkeit sowie [Gson converter addition](https://github.com/square/retrofit/tree/trunk/retrofit-converters/gson) für die Analyse von HTTP-Antworten hinzufügen. *Ersetzen Sie im folgenden Code *`<version>`* durch die aktuelle Versionsnummer des Chat Android SDKs (z. B. 1.1.0).*

**Kotlin-Skript:**

```
// ./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")
}
```

Um ein Chat-Token abzurufen, müssen wir eine POST-HTTP-Anfrage von unserer `chatterbox`-App aus stellen. Wir definieren die Anfrage in einer Schnittstelle, die Retrofit implementieren soll. (Siehe [Retrofit-Dokumentation](https://square.github.io/retrofit/). Machen Sie sich außerdem mit der Spezifikation des Vorgangs [CreateChatToken](https://docs.aws.amazon.com/ivs/latest/ChatAPIReference/API_CreateChatToken.html#API_CreateChatToken_RequestBody) vertraut.)

**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)
   }
}
```

Jetzt, da das Netzwerk eingerichtet ist, ist es an der Zeit, eine Funktion hinzuzufügen, die für die Erstellung und Verwaltung unseres Chat-Tokens verantwortlich ist. Wir fügen sie zu `MainActivity.kt` hinzu, das bei der [Generierung](#chat-kotlin-rooms-chatterbox) des Projekts automatisch erstellt wurde:

**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)
         }
      })
   }
}
```

## Nächste Schritte
<a name="chat-kotlin-rooms-next-steps"></a>

Nachdem Sie nun eine Chatraum-Verbindung hergestellt haben, fahren Sie mit Teil 2 dieses Tutorials für Kotlin-Coroutines fort, [Nachrichten und Ereignisse](chat-sdk-kotlin-tutorial-messages-events.md).