Broadcast
Send messages to all clients in a channel — perfect for chat, notifications, and collaborative features.
Send a Message
- JavaScript
- Dart/Flutter
- Swift
- Kotlin
- Java
- C#
- C++
const channel = client.realtime.channel('chat-room');
channel.send('message', {
text: 'Hello everyone!',
sender: 'Jane',
});
final channel = client.realtime.channel('chat-room');
channel.send('message', {
'text': 'Hello everyone!',
'sender': 'Jane',
});
let channel = client.realtime.channel("chat-room")
channel.send("message", payload: [
"text": "Hello everyone!",
"sender": "Jane"
])
val channel = client.realtime.channel("chat-room")
channel.send("message", mapOf(
"text" to "Hello everyone!",
"sender" to "Jane"
))
var channel = client.realtime().channel("chat-room");
channel.send("message", Map.of(
"text", "Hello everyone!",
"sender", "Jane"
));
var channel = client.Realtime.Channel("chat-room");
channel.Send("message", new() {
["text"] = "Hello everyone!",
["sender"] = "Jane",
});
auto channel = client.realtime().channel("chat-room");
channel.send("message", R"({"text": "Hello everyone!", "sender": "Jane"})");
Listen for Messages
- JavaScript
- Dart/Flutter
- Swift
- Kotlin
- Java
- C#
- C++
// Listen for a specific event type
channel.on('message', (payload, meta) => {
console.log(`${meta.userId}: ${payload.text}`);
});
// Listen for all messages
channel.onMessage((event, payload, meta) => {
console.log(`[${event}]`, payload);
});
channel.on('message', (payload, meta) {
print('${meta.userId}: ${payload['text']}');
});
channel.onMessage((event, payload, meta) {
print('[$event] $payload');
});
channel.on("message") { payload, meta in
print("\(meta.userId): \(payload["text"] ?? "")")
}
channel.onMessage { event, payload, meta in
print("[\(event)] \(payload)")
}
channel.on("message") { payload, meta ->
println("${meta.userId}: ${payload["text"]}")
}
channel.onMessage { event, payload, meta ->
println("[$event] $payload")
}
channel.on("message", (payload, meta) -> {
System.out.println(meta.getUserId() + ": " + payload.get("text"));
});
channel.onMessage((event, payload, meta) -> {
System.out.println("[" + event + "] " + payload);
});
channel.On("message", (payload, meta) => {
Console.WriteLine($"{meta.UserId}: {payload["text"]}");
});
channel.OnMessage((evt, payload, meta) => {
Console.WriteLine($"[{evt}] {payload}");
});
channel.on("message", [](const nlohmann::json& payload, const eb::BroadcastMeta& meta) {
std::cout << meta.userId << ": " << payload["text"] << std::endl;
});
Self-Receive Behavior
By default, broadcast messages are not sent back to the sender (excludeSelf defaults to true). To receive your own messages, explicitly set excludeSelf: false:
- JavaScript
- Dart/Flutter
- Swift
- Kotlin
// Default: you do NOT receive your own messages
channel.send('message', { text: 'Hello' });
// Opt-in: receive your own messages
channel.send('message', { text: 'Hello' }, { excludeSelf: false });
// Default: you do NOT receive your own messages
channel.send('message', {'text': 'Hello'});
// Opt-in: receive your own messages
channel.send('message', {'text': 'Hello'}, excludeSelf: false);
// Default: you do NOT receive your own messages
channel.send("message", payload: ["text": "Hello"])
// Opt-in: receive your own messages
channel.send("message", payload: ["text": "Hello"], excludeSelf: false)
// Default: you do NOT receive your own messages
channel.send("message", mapOf("text" to "Hello"))
// Opt-in: receive your own messages
channel.send("message", mapOf("text" to "Hello"), excludeSelf = false)
WebSocket Message Format
Under the hood, the SDK sends a broadcast message with an optional excludeSelf field:
{
"type": "broadcast",
"event": "cursor-move",
"payload": { "x": 100, "y": 200 },
"excludeSelf": true
}
| Field | Type | Default | Description |
|---|---|---|---|
event | string | — | Custom event name |
payload | object | — | JSON data to broadcast |
excludeSelf | boolean | true | When true, the sender does not receive their own broadcast. Set to false to include the sender in broadcast recipients. |
Broadcast Event Format
When a broadcast message is received, the server delivers it as a broadcast_event:
{
"type": "broadcast_event",
"event": "message",
"payload": { "text": "Hello everyone!", "sender": "Jane" },
"senderId": "conn_abc123",
"userId": "user_456"
}
| Field | Description |
|---|---|
event | The custom event name passed to send() |
payload | The JSON data passed to send() |
senderId | Unique connection ID of the sender |
userId | Authenticated user ID of the sender |
Channel Security
Broadcast channels use realtime.namespaces rules in edgebase.config.ts. Two rules are available:
subscribe— Who can join the channel and receive messagespublish— Who can send messages to the channel
realtime: {
namespaces: {
'broadcast:chat-*': {
access: {
subscribe(auth) { return auth !== null },
publish(auth) { return auth !== null },
},
},
'broadcast:public-*': {
access: {
subscribe() { return true }, // Anyone can listen
publish(auth) { return auth !== null }, // Only authenticated can send
},
},
},
}
Channels with no matching rule default to authenticated users only (deny by default, regardless of release mode). See Access Rules for the full security model.
Server-Side Broadcast
Admin SDKs can broadcast messages via the REST API, bypassing channel rules (Service Key = admin authority). That applies across all Admin SDKs.
- JavaScript (Admin)
- Dart (Admin)
- Kotlin (Admin)
- Java (Admin)
- Scala (Admin)
- Python (Admin)
- Go (Admin)
- PHP (Admin)
- Rust (Admin)
- C# (Admin)
- Ruby (Admin)
- Elixir (Admin)
import { createAdminClient } from '@edgebase/admin';
const admin = createAdminClient('https://my-app.edgebase.dev', {
serviceKey: process.env.EDGEBASE_SERVICE_KEY,
});
await admin.broadcast('chat-room', 'message', {
text: 'System announcement',
sender: 'system',
});
import 'dart:io';
import 'package:edgebase_admin/edgebase_admin.dart';
final admin = AdminEdgeBase(
'https://my-app.edgebase.dev',
serviceKey: Platform.environment['EDGEBASE_SERVICE_KEY']!,
);
await admin.broadcast('chat-room', 'message', {
'text': 'System announcement',
'sender': 'system',
});
import dev.edgebase.sdk.admin.AdminEdgeBase
val admin = AdminEdgeBase(
"https://my-app.edgebase.dev",
serviceKey = System.getenv("EDGEBASE_SERVICE_KEY") ?: ""
)
admin.broadcast("chat-room", "message", mapOf(
"text" to "System announcement",
"sender" to "system",
))
import dev.edgebase.sdk.admin.*;
AdminEdgeBase admin = EdgeBase.admin(
"https://my-app.edgebase.dev",
System.getenv("EDGEBASE_SERVICE_KEY")
);
admin.broadcast("chat-room", "message", Map.of(
"text", "System announcement",
"sender", "system"
));
import dev.edgebase.sdk.scala.admin.AdminEdgeBase
val admin = AdminEdgeBase(
"https://my-app.edgebase.dev",
sys.env("EDGEBASE_SERVICE_KEY")
)
admin.broadcast("chat-room", "message", Map(
"text" -> "System announcement",
"sender" -> "system"
))
import os
from edgebase_admin import AdminClient
admin = AdminClient(
'https://my-app.edgebase.dev',
service_key=os.environ['EDGEBASE_SERVICE_KEY'],
)
admin.broadcast('chat-room', 'message', {
'text': 'System announcement',
'sender': 'system',
})
import (
"context"
"os"
edgebase "github.com/edgebase/sdk-go"
)
ctx := context.Background()
admin := edgebase.NewAdminClient("https://my-app.edgebase.dev", os.Getenv("EDGEBASE_SERVICE_KEY"))
_ = admin.Broadcast(ctx, "chat-room", "message", map[string]interface{}{
"text": "System announcement",
"sender": "system",
})
use EdgeBase\Admin\AdminClient;
$admin = new AdminClient('https://my-app.edgebase.dev', getenv('EDGEBASE_SERVICE_KEY'));
$admin->broadcast('chat-room', 'message', [
'text' => 'System announcement',
'sender' => 'system',
]);
use edgebase_admin::EdgeBase;
use serde_json::json;
let admin = EdgeBase::server(
"https://my-app.edgebase.dev",
&std::env::var("EDGEBASE_SERVICE_KEY").unwrap(),
)?;
admin.broadcast("chat-room", "message", json!({
"text": "System announcement",
"sender": "system",
})).await?;
using System;
using System.Collections.Generic;
using EdgeBase.Admin;
var admin = new AdminClient(
"https://my-app.edgebase.dev",
Environment.GetEnvironmentVariable("EDGEBASE_SERVICE_KEY")!
);
await admin.BroadcastAsync("chat-room", "message", new Dictionary<string, object?> {
["text"] = "System announcement",
["sender"] = "system",
});
require "edgebase_admin"
admin = EdgebaseAdmin::AdminClient.new(
"https://my-app.edgebase.dev",
service_key: ENV.fetch("EDGEBASE_SERVICE_KEY")
)
admin.broadcast("chat-room", "message", {
"text" => "System announcement",
"sender" => "system"
})
alias EdgeBaseAdmin
admin =
EdgeBaseAdmin.new("https://my-app.edgebase.dev",
service_key: System.fetch_env!("EDGEBASE_SERVICE_KEY")
)
EdgeBaseAdmin.broadcast!(admin, "chat-room", "message", %{
"text" => "System announcement",
"sender" => "system"
})
REST Endpoint
POST /api/realtime/broadcast
Headers:
X-EdgeBase-Service-Key: <your-service-key>(required)Content-Type: application/json
Body:
{
"channel": "chat-room",
"event": "message",
"payload": { "text": "System announcement" }
}
Responses:
| Status | Description |
|---|---|
200 | { "ok": true } |
400 | Invalid JSON or missing channel/event |
401 | Invalid Service Key |
403 | Service Key required |
App Functions Integration
Inside App Functions, use context.admin.broadcast():
export default async function onPostCreate(doc, context) {
await context.admin.broadcast('updates', 'new-post', {
id: doc.id,
title: doc.data.title,
});
}
Broadcast is fire-and-forget pub/sub messaging — there's no server-side state. If you need server-authoritative state management (game logic, collaborative editing, etc.), use Room instead.