Supabase Real-time Channels provide a mechanism for real-time communication between clients and servers. They enable bidirectional communication, allowing for instant updates and notifications without the need for polling. Real-time Channels are built on top of Phoenix Channels and WebSockets, providing a reliable and scalable solution for real-time applications.
- Bidirectional Communication: Two-way communication between clients and servers
- Low Latency: Instant updates with minimal delay
- Scalable Architecture: Designed to handle thousands of concurrent connections
- Secure Authentication: JWT-based authentication for secure connections
- Presence Tracking: Track online users and their state
- Broadcast Capabilities: Send messages to multiple clients simultaneously
- Database Integration: Subscribe to database changes in real-time
- Edge Function Integration: Trigger edge functions from real-time events
Supabase Real-time Channels are built on a publish-subscribe model. Clients subscribe to channels, and servers publish messages to those channels. When a message is published to a channel, all subscribed clients receive the message.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ Client │◄───▶│ Supabase │◄───▶│ Database │
│ │ │ Real-time │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
▲ ▲ ▲
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ Client │◄───▶│ Channel │◄───▶│ Edge │
│ │ │ │ │ Function │
└─────────────┘ └─────────────┘ └─────────────┘
Supabase Real-time Channels support several types of channels:
Presence channels track the online status and state of connected clients. They are useful for building features like online indicators, typing indicators, and user activity tracking.
// Subscribe to a presence channel
const channel = supabase.channel('room:123', {
config: {
presence: {
key: user.id,
},
},
});
// Track presence changes
channel.on('presence', { event: 'sync' }, () => {
const state = channel.presenceState();
console.log('Current state:', state);
});
// Update presence state
channel.track({ user_id: user.id, status: 'online' });
Broadcast channels allow clients to send messages to all other connected clients. They are useful for building chat applications, collaborative editing, and real-time notifications.
// Subscribe to a broadcast channel
const channel = supabase.channel('room:123');
// Listen for broadcast messages
channel.on('broadcast', { event: 'message' }, (payload) => {
console.log('Received message:', payload);
});
// Send a broadcast message
channel.send({
type: 'broadcast',
event: 'message',
payload: { text: 'Hello, world!' },
});
Database channels allow clients to subscribe to database changes. They are useful for building real-time dashboards, activity feeds, and collaborative applications.
// Subscribe to database changes
const channel = supabase
.channel('db-changes')
.on(
'postgres_changes',
{
event: '*',
schema: 'public',
table: 'messages',
},
(payload) => {
console.log('Change received:', payload);
}
)
.subscribe();
Real-time Channels can be integrated with Edge Functions to create powerful real-time applications. Edge Functions can subscribe to channels, process messages, and publish responses.
// In an Edge Function
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/[email protected]";
const supabaseClient = createClient(
Deno.env.get("SUPABASE_URL") ?? "",
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") ?? ""
);
serve(async (req) => {
// Subscribe to a channel
const channel = supabaseClient.channel('room:123');
// Listen for messages
channel.on('broadcast', { event: 'message' }, async (payload) => {
// Process the message
const response = await processMessage(payload);
// Send a response
channel.send({
type: 'broadcast',
event: 'response',
payload: response,
});
});
// Subscribe to the channel
channel.subscribe();
return new Response(
JSON.stringify({ message: "Subscribed to channel" }),
{ headers: { "Content-Type": "application/json" } }
);
});
Real-time Channels support JWT-based authentication. Clients can authenticate using a Supabase JWT token, which is automatically handled by the Supabase client library.
// Create a Supabase client with authentication
const supabase = createClient(
'https://your-project-ref.supabase.co',
'your-anon-key',
{
auth: {
persistSession: true,
},
}
);
// Sign in
const { data, error } = await supabase.auth.signInWithPassword({
email: '[email protected]',
password: 'password',
});
// After authentication, channels will use the JWT token
const channel = supabase.channel('room:123');
Real-time Channels provide error handling mechanisms to handle connection issues, authentication failures, and other errors.
// Handle channel errors
channel.on('system', { event: 'error' }, (error) => {
console.error('Channel error:', error);
});
// Handle disconnections
channel.on('system', { event: 'disconnect' }, () => {
console.log('Disconnected from channel');
});
// Handle reconnections
channel.on('system', { event: 'reconnect' }, () => {
console.log('Reconnected to channel');
});
- Use Presence for User Status: Leverage presence channels for tracking user status and activity
- Implement Retry Logic: Handle disconnections and implement retry logic for reliable connections
- Optimize Payload Size: Keep message payloads small for better performance
- Use Appropriate Channel Types: Choose the right channel type for your use case
- Implement Error Handling: Handle errors and disconnections gracefully
- Secure Your Channels: Use row-level security and proper authentication
- Monitor Channel Usage: Keep track of channel usage and performance
- Message Size: Maximum message size is 8KB
- Rate Limiting: Channels are subject to rate limiting
- Connection Limits: There are limits on the number of concurrent connections
- Persistence: Messages are not persisted by default
Created by rUv, Agentics Foundation founder.