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.
PubSub calls need a joined room. Show the chat, and subscribe, after Events.roomJoined.
Implementing Chat
- 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
CHATas the topic for this one. So let us lets create a message input and send button to publish the messages using thepubSubfrom theRoomobject.publish()returns aFuturethat throws aVideoSDKErrorwhen 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"),
),
],
),
]
);
}
}
- Final step in the group chat would be to display the messages others send. For this we will subscribe to the topic
CHATwith aPubSubMessageListenerand keep every message it receives. Messages sent withpersist: truebefore you subscribed arrive together ononOldMessagesReceived, so the list starts with the chat history. New messages arrive one at a time ononMessageReceived.
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

