Skip to main content
Version: 5.x.x

Chat using PubSub - Flutter

For the communication or any kind of messaging in between the participants, VideoSDK provides pubSub which use Publish-Subscribe mechanism and can be used to develop wide variety of functionalities. For example, participants could use it to send chat messages to each other, share files or other media, or even trigger actions like muting or unmuting audio or video.

Now we will see, how we can use PubSub to implement Chat functionality. If you are not familiar with the PubSub mechanism, you can follow this guide.

note

PubSub calls need a joined room. Show the chat, and subscribe, after Events.roomJoined.

Implementing Chat​

  1. First step in creating a group chat is choosing the topic which all the participants will publish and subscribe to send and receive the messages. We will be using CHAT as the topic for this one. So let us lets create a message input and send button to publish the messages using the pubSub from the Room object. publish() returns a Future that throws a VideoSDKError when the message cannot be sent.
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class ChatView extends StatefulWidget {
final Room room;
...
}

class _ChatViewState extends State<ChatView> {

final msgTextController = TextEditingController();


@override
void initState() {
...
}

@override
Widget build(BuildContext context) {
return Column(
children:[
Row(
children: [
Expanded(
child: TextField(
style: TextStyle(
fontSize:16,
fontWeight: FontWeight.w500,
),
controller: msgTextController,
onChanged: (value) => setState(() {
msgTextController.text;
}),
decoration: const InputDecoration(
hintText: "Write your message",
border: InputBorder.none,
),
),
),
ElevatedButton(
onPressed: () async {
if (msgTextController.text.trim().isEmpty) return;
try {
await widget.room.pubSub.publish(
"CHAT",
msgTextController.text,
const PubSubPublishOptions(persist: true),
);
msgTextController.clear();
} on VideoSDKError catch (error) {
log("Could not send the message: ${error.code} ${error.name}");
}
},
child: const Text("Send Message"),
),
],
),
]
);
}

}
  1. Final step in the group chat would be to display the messages others send. For this we will subscribe to the topic CHAT with a PubSubMessageListener and keep every message it receives. Messages sent with persist: true before you subscribed arrive together on onOldMessagesReceived, so the list starts with the chat history. New messages arrive one at a time on onMessageReceived.
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class ChatView extends StatefulWidget {
final Room room;
...
}

class _ChatViewState extends State<ChatView> {

// Messages on the CHAT topic
final List<PubSubMessage> messages = [];

// Keep the listener: unsubscribe() takes the same object
late final PubSubMessageListener chatListener = PubSubMessageListener(
onOldMessagesReceived: historyHandler,
onMessageReceived: messageHandler,
);

@override
void initState() {
...

// Subscribing 'CHAT' Topic
subscribeToChat();
}

Future<void> subscribeToChat() async {
try {
await widget.room.pubSub.subscribe("CHAT", chatListener);
} on VideoSDKError catch (error) {
log("Could not subscribe to CHAT: ${error.code} ${error.name}");
}
}

//Handler for the messages sent before you subscribed
void historyHandler(List<PubSubMessage> history, PubSubHistoryInfo info) {
if (mounted) {
setState(() => messages.insertAll(0, history));
}
}

//Handler which will be called for every new message on the topic
void messageHandler(PubSubMessage message) {
if (mounted) {
setState(() => messages.add(message));
}
}

@override
Widget build(BuildContext context) {
return Column(
children:[
Expanded(
child: SingleChildScrollView(
reverse: true,
child: Column(
children: messages
.map(
(message) => Text(
message.message
),
)
.toList(),
),
),
),

...
//Send Message code Here
]
);
}

@override
void dispose() {
// Unsubscribe. The listener stops at once, even when this call fails
// because the room has already left.
widget.room.pubSub
.unsubscribe("CHAT", chatListener)
.catchError((Object error) {});
super.dispose();
}
}

Displaying Latest Message Notification​

You may want to show the notification to the user when new message arrives. So lets continue our example and add alert for the new messages. Only new messages reach onMessageReceived, so the alert goes there; the history on onOldMessagesReceived does not trigger it.

import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';

class ChatView extends StatefulWidget {
final Room room;
...
}

class _ChatViewState extends State<ChatView> {

@override
void initState() {
...
}

//Handler which will be called for every new message on the topic
void messageHandler(PubSubMessage message) {
if (!mounted) return;
//Show snackbar for the new message
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
message.message,
overflow: TextOverflow.fade,
),
));
setState(() => messages.add(message));
}

@override
Widget build(BuildContext context) {
return Column(
children:[
...
]
);
}

@override
void dispose() {
...
}
}

Downloading Chat Messages​

All the messages from the PubSub which where published with persist : true and can be downloaded as an .csv file. This file will be available in the VideoSDK dashboard as well as throught the Sessions API.

API Reference​

The API references for all the methods and events utilised in this guide are provided below.

Got a Question? Ask us on discord