Chat during Live Stream - Flutter
Enhance your live stream experience by enabling real-time audience chat using VideoSDK's PubSub
class. Whether you’re streaming a webinar, online event, or an interactive session, integrating a chat system lets your viewers engage, ask questions, and react instantly. This guide shows how to build a group or private chat interface for a live stream using the Publish-Subscribe (PubSub) mechanism.
This guide focuses on using PubSub to implement Chat functionality. If you are not familiar with the PubSub mechanism and PubSub
class, you can follow this guide.
Implementing Chat​
Group Chat
(Public Chat for All Viewers)​
- 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 thepubSub
from theRoom
object.
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() {
...
// Subscribing 'CHAT' Topic
widget.meeting.pubSub
.subscribe("CHAT", messageHandler)
.then((value) => setState((() => messages = value)));
}
//Handler which will be called when new mesasge is received
void messageHandler(PubSubMessage message) {
setState(() => messages!.messages.add(message));
}
@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:(){
if(!msgTextController.text.trim().isEmpty){
widget.room.pubSub
.publish(
"CHAT",
msgTextController.text,
const PubSubPublishOptions(
persist: true),
)
.then(
(value) => msgTextController.clear())
}
},
child: const Text("Send Message"),
),
],
),
]
);
}
}
- Final step in the group chat would be to display the messages others send. For this will use the
messages
and display all the messages by subscribing to the topicCHAT
.
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';
class ChatView extends StatefulWidget {
final Room room;
...
}
class _ChatViewState extends State<ChatView> {
// PubSubMessages
PubSubMessages? messages;
@override
void initState() {
...
// Subscribing 'CHAT' Topic
widget.meeting.pubSub
.subscribe("CHAT", messageHandler)
.then((value) => setState((() => messages = value)));
}
//Handler which will be called when new mesasge is received
void messageHandler(PubSubMessage message) {
setState(() => messages!.messages.add(message));
}
@override
Widget build(BuildContext context) {
return Column(
children:[
Expanded(
child: messages == null
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
reverse: true,
child: Column(
children: messages!.messages
.map(
(message) => Text(
message.message
),
)
.toList(),
),
),
),
...
//Send Message code Here
]
);
}
@override
void dispose() {
// Unsubscribe
widget.room.pubSub.unsubscribe("CHAT", messageHandler);
super.dispose();
}
}
Private Chat
(1:1 between Host and Viewer)​
Private messaging is ideal when a host or moderator needs to directly respond to a viewer’s question. This can be achieved using the sendOnly
parameter in PubSubPublishOptions
.
import 'package:flutter/material.dart';
import 'package:videosdk/videosdk.dart';
class ChatView extends StatefulWidget {
final Room room;
...
}
class _ChatViewState extends State<ChatView> {
//...
@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:(){
if(!msgTextController.text.trim().isEmpty){
// Pass the participantId of the participant to whom you want to send the message.
widget.room.pubSub
.publish(
"CHAT",
msgTextController.text,
const PubSubPublishOptions(
persist: true, sendOnly: ["xyz"]),
)
.then(
(value) => msgTextController.clear())
}
},
child: const Text("Send Message"),
),
],
),
]
);
}
}
Displaying Latest Message Notificaiton​
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 images.
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 when new mesasge is received
void messageHandler(PubSubMessage message) {
//Show snackbar on new message
if(context.mounted){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
message.message,
overflow: TextOverflow.fade,
),
));
}
setState(() => messages!.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