

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# IVS Chat Client Messaging SDK: React Native Tutorial Bagian 2: Pesan dan Acara
<a name="chat-sdk-react-tutorial-messages-events"></a>

Bagian kedua (dan terakhir) dari tutorial ini dipecah menjadi beberapa bagian:

1. [Berlangganan Peristiwa Pesan Obrolan](#chat-react-messages-events-subscribe)

1. [Menampilkan Pesan yang Diterima](#chat-react-messages-events-show)

   1.  [Membuat Komponen Pesan](#chat-react-messages-create-component)

   1. [Mengenali Pesan yang Dikirim oleh Pengguna Saat Ini](#chat-react-messages-recognize)

   1. [Me-render Daftar Pesan Obrolan](#chat-react-messages-render-list)

1. [Melakukan Tindakan di Ruang Obrolan](#chat-react-messages-events-room-actions)

   1. [Mengirim Pesan](#chat-react-room-actions-sending-message)

   1. [Menghapus Pesan](#chat-react-room-actions-deleting-message)

1. [Langkah Berikutnya](#chat-react-messages-events-next-steps)

**Catatan**: Dalam beberapa kasus, contoh kode untuk JavaScript dan TypeScript identik, sehingga digabungkan.

## Prasyarat
<a name="chat-react-messages-events-prerequisite"></a>

Pastikan Anda telah menyelesaikan Bagian 1 dari tutorial ini, [Ruang Obrolan](chat-sdk-react-tutorial-chat-rooms.md).

## Berlangganan Peristiwa Pesan Obrolan
<a name="chat-react-messages-events-subscribe"></a>

Instans `ChatRoom` menggunakan peristiwa untuk berkomunikasi ketika peristiwa terjadi di ruang obrolan. Untuk mulai mengimplementasikan pengalaman obrolan, Anda harus menunjukkan kepada pengguna saat orang lain mengirim pesan di ruang yang terhubung dengan mereka.

Di sini, Anda berlangganan peristiwa pesan obrolan. Selanjutnya, kami akan menunjukkan cara memperbarui daftar pesan yang Anda buat, yang diperbarui dengan setiap pesan/peristiwa.

Di `App` Anda, di dalam hook `useEffect`, berlangganan semua peristiwa pesan:

**TypeScript/JavaScript**:

```
// App.tsx / App.jsx

useEffect(() => {
  // ...
  const unsubscribeOnMessageReceived = room.addListener('message', (message) => {});

  return () => {
    // ...
    unsubscribeOnMessageReceived();
  };
}, []);
```

## Menampilkan Pesan yang Diterima
<a name="chat-react-messages-events-show"></a>

Menerima pesan adalah bagian inti dari pengalaman obrolan. Dengan SDK JS Obrolan, Anda dapat menyiapkan kode agar dapat dengan mudah menerima peristiwa dari pengguna lain yang terhubung ke ruang obrolan.

Selanjutnya, kami akan menunjukkan cara melakukan tindakan di ruang obrolan yang memanfaatkan komponen yang Anda buat di sini.

Di `App` Anda, tentukan status bernama `messages` dengan tipe array `ChatMessage` yang bernama `messages`:

------
#### [ TypeScript ]

```
// App.tsx

// ...

import { ChatRoom, ChatMessage, ConnectionState } from 'amazon-ivs-chat-messaging';

export default function App() {
  const [messages, setMessages] = useState<ChatMessage[]>([]);

  //...
}
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

import { ChatRoom, ConnectionState } from 'amazon-ivs-chat-messaging';

export default function App() {
  const [messages, setMessages] = useState([]);

  //...
}
```

------

Selanjutnya, di fungsi pendengar `message`, tambahkan `message` ke array `messages`:

**TypeScript/JavaScript**:

```
// App.tsx / App.jsx

// ...

const unsubscribeOnMessageReceived = room.addListener('message', (message) => {
  setMessages((msgs) => [...msgs, message]);
});

// ...
```

Di bawah ini, kita akan menjalankan langkah demi langkah untuk menampilkan pesan yang diterima:

1.  [Membuat Komponen Pesan](#chat-react-messages-create-component)

1. [Mengenali Pesan yang Dikirim oleh Pengguna Saat Ini](#chat-react-messages-recognize)

1. [Me-render Daftar Pesan Obrolan](#chat-react-messages-render-list)

### Membuat Komponen Pesan
<a name="chat-react-messages-create-component"></a>

Komponen `Message` bertanggung jawab untuk me-render konten pesan yang diterima oleh ruang obrolan Anda. Di bagian ini, Anda membuat komponen pesan untuk me-render pesan obrolan individu di `App`.

Buat file baru di direktori `src` dan beri nama `Message`. Berikan tipe `ChatMessage` untuk komponen ini, dan berikan string `content` dari properti `ChatMessage` untuk menampilkan teks pesan yang diterima dari pendengar pesan ruang obrolan. Di Navigator Proyek, buka `Message`.

------
#### [ TypeScript ]

```
// Message.tsx

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { ChatMessage } from 'amazon-ivs-chat-messaging';

type Props = {
  message: ChatMessage;
}

export const Message = ({ message }: Props) => {
  return (
    <View style={styles.root}>
      <Text>{message.sender.userId}</Text>
      <Text style={styles.textContent}>{message.content}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    backgroundColor: 'silver',
    padding: 6,
    borderRadius: 10,
    marginHorizontal: 12,
    marginVertical: 5,
    marginRight: 50,
  },
  textContent: {
    fontSize: 17,
    fontWeight: '500',
    flexShrink: 1,
  },
});
```

------
#### [ JavaScript ]

```
// Message.jsx

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export const Message = ({ message }) => {
  return (
    <View style={styles.root}>
      <Text>{message.sender.userId}</Text>
      <Text style={styles.textContent}>{message.content}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    backgroundColor: 'silver',
    padding: 6,
    borderRadius: 10,
    marginHorizontal: 12,
    marginVertical: 5,
    marginRight: 50,
  },
  textContent: {
    fontSize: 17,
    fontWeight: '500',
    flexShrink: 1,
  },
});
```

------

**Tip**: Gunakan komponen ini untuk menyimpan properti berbeda yang ingin Anda render di baris pesan; misalnya, avatar URLs, nama pengguna, dan cap waktu saat pesan dikirim.

### Mengenali Pesan yang Dikirim oleh Pengguna Saat Ini
<a name="chat-react-messages-recognize"></a>

Untuk mengenali pesan yang dikirim oleh pengguna saat ini, kita mengubah kode dan membuat konteks React untuk menyimpan `userId` pengguna saat ini.

Buat file baru di direktori `src` dan beri nama `UserContext`:

------
#### [ TypeScript ]

```
// UserContext.tsx

import React from 'react';

const UserContext = React.createContext<string | undefined>(undefined);

export const useUserContext = () => {
  const context = React.useContext(UserContext);

  if (context === undefined) {
    throw new Error('useUserContext must be within UserProvider');
  }

  return context;
};

export const UserProvider = UserContext.Provider;
```

------
#### [ JavaScript ]

```
// UserContext.jsx

import React from 'react';

const UserContext = React.createContext(undefined);

export const useUserContext = () => {
  const context = React.useContext(UserContext);

  if (context === undefined) {
    throw new Error('useUserContext must be within UserProvider');
  }

  return context;
};

export const UserProvider = UserContext.Provider;
```

------

Catatan: Di sini kita menggunakan hook `useState` untuk menyimpan nilai `userId`. Ke depannya, Anda dapat memanfaatkan `setUserId` untuk mengubah konteks pengguna atau untuk tujuan login.

Selanjutnya, ganti `userId` pada parameter pertama yang diberikan ke `tokenProvider`, dengan menggunakan konteks yang dibuat sebelumnya. Pastikan untuk menambahkan kemampuan `SEND_MESSAGE` ke penyedia token Anda, seperti yang ditentukan di bawah ini; kemampuan ini diperlukan untuk mengirim pesan.:

------
#### [ TypeScript ]

```
// App.tsx

// ...

import { useUserContext } from './UserContext';

// ...


export default function App() {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const userId = useUserContext();
  const [room] = useState(
    () =>
      new ChatRoom({
        regionOrUrl: process.env.REGION,
        tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE']),
      }),
  );

  // ...
}
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

import { useUserContext } from './UserContext';

// ...


export default function App() {
  const [messages, setMessages] = useState([]);
  const userId = useUserContext();
  const [room] = useState(
    () =>
      new ChatRoom({
        regionOrUrl: process.env.REGION,
        tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE']),
      }),
  );

  // ...
}
```

------

Dalam komponen `Message` Anda, gunakan `UserContext` yang dibuat sebelumnya, nyatakan variabel `isMine`, cocokkan `userId` pengirim dengan `userId` dari konteks, dan terapkan gaya pesan yang berbeda untuk pengguna saat ini.

------
#### [ TypeScript ]

```
// Message.tsx

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

type Props = {
  message: ChatMessage;
}

export const Message = ({ message }: Props) => {
  const userId = useUserContext();

  const isMine = message.sender.userId === userId;

  return (
    <View style={[styles.root, isMine && styles.mine]}>
      {!isMine && <Text>{message.sender.userId}</Text>}
      <Text style={styles.textContent}>{message.content}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    backgroundColor: 'silver',
    padding: 6,
    borderRadius: 10,
    marginHorizontal: 12,
    marginVertical: 5,
    marginRight: 50,
  },
  textContent: {
    fontSize: 17,
    fontWeight: '500',
    flexShrink: 1,
  },
  mine: {
    flexDirection: 'row-reverse',
    backgroundColor: 'lightblue',
  },
});
```

------
#### [ JavaScript ]

```
// Message.jsx

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

export const Message = ({ message }) => {
  const userId = useUserContext();

  const isMine = message.sender.userId === userId;

  return (
    <View style={[styles.root, isMine && styles.mine]}>
      {!isMine && <Text>{message.sender.userId}</Text>}
      <Text style={styles.textContent}>{message.content}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    backgroundColor: 'silver',
    padding: 6,
    borderRadius: 10,
    marginHorizontal: 12,
    marginVertical: 5,
    marginRight: 50,
  },
  textContent: {
    fontSize: 17,
    fontWeight: '500',
    flexShrink: 1,
  },
  mine: {
    flexDirection: 'row-reverse',
    backgroundColor: 'lightblue',
  },
});
```

------

### Me-render Daftar Pesan Obrolan
<a name="chat-react-messages-render-list"></a>

Sekarang, buat daftar pesan dengan memanfaatkan komponen `FlatList` dan `Message`:

------
#### [ TypeScript ]

```
// App.tsx

// ...

const renderItem = useCallback<ListRenderItem<ChatMessage>>(({ item }) => {
  return (
    <Message key={item.id} message={item} />
  );
}, []);

return (
  <SafeAreaView style={styles.root}>
    <Text>Connection State: {connectionState}</Text>
    <FlatList inverted data={messages} renderItem={renderItem} />
    <View style={styles.messageBar}>
      <MessageInput value={messageToSend} onMessageChange={setMessageToSend} />
      <SendButton disabled={isSendDisabled} onPress={onMessageSend} />
    </View>
  </SafeAreaView>
);

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

const renderItem = useCallback(({ item }) => {
  return (
    <Message key={item.id} message={item} />
  );
}, []);

return (
  <SafeAreaView style={styles.root}>
    <Text>Connection State: {connectionState}</Text>
    <FlatList inverted data={messages} renderItem={renderItem} />
    <View style={styles.messageBar}>
      <MessageInput value={messageToSend} onMessageChange={setMessageToSend} />
      <SendButton disabled={isSendDisabled} onPress={onMessageSend} />
    </View>
  </SafeAreaView>
);

// ...
```

------

Semua potongan puzzle sekarang sudah siap sehingga `App` Anda dapat mulai me-render pesan yang diterima oleh ruang obrolan Anda. Lanjutkan langkah di bawah ini untuk melihat cara melakukan tindakan di ruang obrolan yang memanfaatkan komponen yang telah Anda buat.

## Melakukan Tindakan di Ruang Obrolan
<a name="chat-react-messages-events-room-actions"></a>

Mengirim pesan dan melakukan tindakan moderator adalah beberapa cara utama Anda dalam berinteraksi dengan ruang obrolan. Di sini, Anda akan belajar cara menggunakan berbagai objek permintaan obrolan untuk melakukan tindakan umum di Chatterbox, seperti mengirim pesan, menghapus pesan, dan memutus koneksi pengguna lain.

Semua tindakan di ruang obrolan mengikuti pola umum: untuk setiap tindakan yang Anda lakukan di ruang obrolan, ada objek permintaan yang sesuai. Untuk setiap permintaan, ada objek respons yang sesuai yang Anda terima setelah konfirmasi permintaan.

Selama pengguna Anda diberi kemampuan yang benar saat Anda membuat token obrolan, mereka akan berhasil melakukan tindakan yang sesuai menggunakan objek permintaan untuk melihat permintaan apa yang dapat Anda lakukan di ruang obrolan.

Di bawah ini, kami menjelaskan cara [mengirim pesan](#chat-react-room-actions-sending-message) dan [menghapus pesan](#chat-react-room-actions-deleting-message).

### Mengirim Pesan
<a name="chat-react-room-actions-sending-message"></a>

Kelas `SendMessageRequest` memungkinkan pengiriman pesan di ruang obrolan. Di sini, Anda memodifikasi `App` untuk mengirim permintaan pesan menggunakan komponen yang Anda buat di [Buat Input Pesan](chat-sdk-react-tutorial-chat-rooms.md#chat-react-rooms-message-input) (di Bagian 1 tutorial ini).

Untuk memulai, tentukan properti boolean baru bernama `isSending` dengan hook `useState`. Gunakan properti baru ini untuk mengalihkan status nonaktif elemen `button` Anda, menggunakan konstanta `isSendDisabled`. Di handler peristiwa untuk `SendButton` Anda, kosongkan nilai untuk `messageToSend` dan atur `isSending` ke true.

*Karena Anda akan melakukan panggilan API dari tombol ini, penambahan boolean `isSending` akan membantu mencegah banyaknya panggilan API yang terjadi di waktu yang bersamaan, dengan menonaktifkan interaksi pengguna pada `SendButton` Anda hingga permintaan selesai.*

Catatan: Pengiriman pesan hanya akan berhasil jika Anda menambahkan kemampuan `SEND_MESSAGE` ke penyedia token, seperti yang dibahas di atas dalam [Mengenali Pesan yang Dikirim oleh Pengguna Saat ini](#chat-react-messages-recognize).

**TypeScript/JavaScript**:

```
// App.tsx / App.jsx

// ...

const [isSending, setIsSending] = useState(false);

// ...

const onMessageSend = () => {
  setIsSending(true);
  setMessageToSend('');
};

// ...

const isSendDisabled = connectionState !== 'connected' || isSending;

// ...
```

Siapkan permintaan dengan membuat instans `SendMessageRequest` baru, dengan meneruskan konten pesan ke konstruktor. Setelah mengatur status `isSending` dan `messageToSend`, panggil metode `sendMessage`, yang mengirimkan permintaan ke ruang obrolan. Terakhir, hapus bendera `isSending` saat menerima konfirmasi atau penolakan permintaan.

**TypeScript/JavaScript**:

```
// App.tsx / App.jsx

// ...
import { ChatRoom, ConnectionState, SendMessageRequest } from 'amazon-ivs-chat-messaging'
// ...

const onMessageSend = async () => {
  const request = new SendMessageRequest(messageToSend);
  setIsSending(true);
  setMessageToSend('');

  try {
    const response = await room.sendMessage(request);
  } catch (e) {
    console.log(e);
    // handle the chat error here...
  } finally {
    setIsSending(false);
  }
};

// ...
```

Jalankan Chatterbox: coba mengirim pesan dengan menyusun pesan menggunakan `MessageBar` Anda dan mengetuk `SendButton` Anda. Anda akan melihat pesan terkirim Anda di-render dalam `MessageList` yang dibuat sebelumnya.

### Menghapus Pesan
<a name="chat-react-room-actions-deleting-message"></a>

Untuk menghapus pesan dari ruang obrolan, Anda harus memiliki kemampuan yang tepat. Kemampuan diberikan selama inisialisasi token obrolan yang Anda gunakan saat mengautentikasi ke ruang obrolan. Untuk keperluan bagian ini, `ServerApp` dari [Mengatur Authentication/Authorization Server Lokal](chat-sdk-react-tutorial-chat-rooms.md#chat-react-rooms-auth-server) (di Bagian 1 tutorial ini) memungkinkan Anda menentukan kemampuan moderator. Hal ini dilakukan di aplikasi Anda menggunakan objek `tokenProvider` yang Anda buat di [Membangun Penyedia Token](chat-sdk-react-tutorial-chat-rooms.md#chat-react-rooms-token-provider) (juga di Bagian 1).

Di sini, Anda memodifikasi `Message` dengan menambahkan fungsi untuk menghapus pesan.

Pertama, buka `App.tsx` dan tambahkan kemampuan `DELETE_MESSAGE`. (`capabilities` adalah parameter kedua dari fungsi `tokenProvider` Anda.)

Catatan: Ini adalah cara Anda `ServerApp` menginformasikan Obrolan IVS APIs bahwa pengguna yang dikaitkan dengan token obrolan yang dihasilkan dapat menghapus pesan di ruang obrolan. Dalam situasi dunia nyata, Anda mungkin akan memiliki logika backend yang lebih kompleks untuk mengelola kemampuan pengguna di infrastruktur aplikasi server Anda.

**TypeScript/JavaScript**:

```
// App.tsx / App.jsx

// ...

const [room] = useState(() =>
    new ChatRoom({
      regionOrUrl: process.env.REGION,
      tokenProvider: () => tokenProvider(userId, ['SEND_MESSAGE', 'DELETE_MESSAGE']),
    }),
);

// ...
```

Pada langkah berikutnya, Anda memperbarui `Message` untuk menampilkan tombol hapus.

Tentukan fungsi baru bernama `onDelete`, yang menerima string sebagai salah satu parameternya dan mengembalikan `Promise`. Untuk parameter string, berikan ID pesan komponen Anda.

------
#### [ TypeScript ]

```
// Message.tsx

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

export type Props = {
  message: ChatMessage;
  onDelete(id: string): Promise<void>;
};

export const Message = ({ message, onDelete }: Props) => {
  const userId = useUserContext();

  const isMine = message.sender.userId === userId;
  const handleDelete = () => onDelete(message.id);

  return (
    <View style={[styles.root, isMine && styles.mine]}>
      {!isMine && <Text>{message.sender.userId}</Text>}
      <View style={styles.content}>
        <Text style={styles.textContent}>{message.content}</Text>
        <TouchableOpacity onPress={handleDelete}>
          <Text>Delete<Text/>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    backgroundColor: 'silver',
    padding: 6,
    borderRadius: 10,
    marginHorizontal: 12,
    marginVertical: 5,
    marginRight: 50,
  },
  content: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  textContent: {
    fontSize: 17,
    fontWeight: '500',
    flexShrink: 1,
  },
  mine: {
    flexDirection: 'row-reverse',
    backgroundColor: 'lightblue',
  },
});
```

------
#### [ JavaScript ]

```
// Message.jsx

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { ChatMessage } from 'amazon-ivs-chat-messaging';
import { useUserContext } from './UserContext';

export const Message = ({ message, onDelete }) => {
  const userId = useUserContext();

  const isMine = message.sender.userId === userId;
  const handleDelete = () => onDelete(message.id);

  return (
    <View style={[styles.root, isMine && styles.mine]}>
      {!isMine && <Text>{message.sender.userId}</Text>}
      <View style={styles.content}>
        <Text style={styles.textContent}>{message.content}</Text>
        <TouchableOpacity onPress={handleDelete}>
          <Text>Delete<Text/>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  root: {
    backgroundColor: 'silver',
    padding: 6,
    borderRadius: 10,
    marginHorizontal: 12,
    marginVertical: 5,
    marginRight: 50,
  },
  content: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  textContent: {
    fontSize: 17,
    fontWeight: '500',
    flexShrink: 1,
  },
  mine: {
    flexDirection: 'row-reverse',
    backgroundColor: 'lightblue',
  },
});
```

------

Selanjutnya, Anda memperbarui `renderItem` untuk merefleksikan perubahan terbaru pada komponen `FlatList` Anda.

Di `App`, tentukan fungsi bernama `handleDeleteMessage` dan teruskan ke properti `MessageList onDelete`:

------
#### [ TypeScript ]

```
// App.tsx

// ...

const handleDeleteMessage = async (id: string) => {};

const renderItem = useCallback<ListRenderItem<ChatMessage>>(({ item }) => {
  return (
    <Message key={item.id} message={item} onDelete={handleDeleteMessage} />
  );
}, [handleDeleteMessage]);

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

const handleDeleteMessage = async (id) => {};

const renderItem = useCallback(({ item }) => {
  return (
    <Message key={item.id} message={item} onDelete={handleDeleteMessage} />
  );
}, [handleDeleteMessage]);

// ...
```

------

Siapkan permintaan dengan membuat instans `DeleteMessageRequest` baru, dengan meneruskan ID pesan yang relevan ke parameter konstruktor, dan panggil `deleteMessage` yang menerima permintaan yang disiapkan di atas:

------
#### [ TypeScript ]

```
// App.tsx

// ...

const handleDeleteMessage = async (id: string) => {
  const request = new DeleteMessageRequest(id);
  await room.deleteMessage(request);
};

// ...
```

------
#### [ JavaScript ]

```
// App.jsx

// ...

const handleDeleteMessage = async (id) => {
  const request = new DeleteMessageRequest(id);
  await room.deleteMessage(request);
};

// ...
```

------

Selanjutnya, Anda memperbarui status `messages` untuk merefleksikan daftar pesan baru yang menghilangkan pesan yang baru saja Anda hapus.

Di hook `useEffect`, dengarkan peristiwa `messageDelete` dan perbarui array status `messages` Anda dengan menghapus pesan yang mempunyai ID yang sama dengan parameter `message`.

Catatan: Peristiwa `messageDelete` dapat dimunculkan untuk pesan yang dihapus oleh pengguna saat ini atau pengguna lain di ruang. Dengan menanganinya di handler peristiwa (bukan di samping permintaan `deleteMessage`), Anda dapat menyatukan penanganan hapus-pesan.

**TypeScript/JavaScript**:

```
// App.tsx / App.jsx

// ...

const unsubscribeOnMessageDeleted = room.addListener('messageDelete', (deleteMessageEvent) => {
  setMessages((prev) => prev.filter((message) => message.id !== deleteMessageEvent.id));
});

return () => {
  // ...

  unsubscribeOnMessageDeleted();
};

// ...
```

Sekarang Anda dapat menghapus pengguna dari ruang obrolan di aplikasi obrolan Anda.

## Langkah Berikutnya
<a name="chat-react-messages-events-next-steps"></a>

Sebagai percobaan, coba implementasikan tindakan lain di suatu ruang, seperti memutus koneksi pengguna lain.