|
| 1 | +--- |
| 2 | +title: Echo |
| 3 | +meta_description: "The echo channel option enables per-channel control over whether a client receives its own published messages." |
| 4 | +--- |
| 5 | + |
| 6 | +By default, clients receive their own messages when subscribed to a channel they publish on. This is useful in many applications because it means every subscriber, including the publisher, renders state from the same stream of messages. For example, in a chat application or collaborative editor, a client can publish a message and then update its UI only when that message arrives back on the channel, guaranteeing that all participants see the same ordering and state. |
| 7 | + |
| 8 | +However, this is not always desirable. A client streaming pricing updates, publishing telemetry data, or sending tokens via [AI Transport](/docs/ai-transport) does not need to hear its own messages echoed back. Suppressing echo on these channels reduces unnecessary bandwidth and message processing. |
| 9 | + |
| 10 | +Set `echo` to `false` in the channel `params` to suppress echo on a per-channel basis. As `echo` only applies to channel subscriptions, it is only available when using the realtime interface of an Ably SDK, or when using [SSE](/docs/protocols/sse) or [MQTT](/docs/protocols/mqtt). |
| 11 | + |
| 12 | +## When to suppress echo <a id="when"/> |
| 13 | + |
| 14 | +Suppressing echo per-channel is useful when a client publishes and subscribes on the same channel but does not need its own messages back: |
| 15 | + |
| 16 | +- **Streaming data**: A client publishing live pricing updates, sensor readings, or telemetry to a channel does not need those messages echoed back. Suppressing echo avoids redundant processing and reduces bandwidth. |
| 17 | +- **AI token streaming**: An [AI Transport](/docs/ai-transport) agent publishes tokens at high frequency and subscribes for steering or control messages. Echoing every token back to the publishing agent is wasteful. |
| 18 | +- **RPC over channels**: A caller publishes a request and subscribes for the response on the same channel. The caller already knows what it sent. |
| 19 | +- **Mixed workloads**: Some channels on a connection need echo, such as collaborative editing where a client confirms its updates, while others do not, such as notification or logging channels. |
| 20 | + |
| 21 | +The connection-level [`echoMessages`](/docs/api/realtime-sdk/types#client-options) option disables echo across all channels on a connection. The `echo` channel param provides finer control, disabling echo on specific channels while leaving others unaffected. |
| 22 | + |
| 23 | +## Suppress echo on a channel <a id="suppress"/> |
| 24 | + |
| 25 | +Set the `echo` param to `false` when obtaining a channel instance: |
| 26 | + |
| 27 | +<Code> |
| 28 | +```realtime_javascript |
| 29 | +const channel = realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', { |
| 30 | + params: { echo: 'false' } |
| 31 | +}); |
| 32 | +
|
| 33 | +await channel.subscribe((message) => { |
| 34 | + // Only receives messages from other clients, not from this client |
| 35 | + console.log('Received:', message.data); |
| 36 | +}); |
| 37 | +``` |
| 38 | + |
| 39 | +```realtime_nodejs |
| 40 | +const channel = realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', { |
| 41 | + params: { echo: 'false' } |
| 42 | +}); |
| 43 | +
|
| 44 | +await channel.subscribe((message) => { |
| 45 | + // Only receives messages from other clients, not from this client |
| 46 | + console.log('Received:', message.data); |
| 47 | +}); |
| 48 | +``` |
| 49 | + |
| 50 | +```realtime_java |
| 51 | +ChannelOptions channelOpts = new ChannelOptions(); |
| 52 | +channelOpts.params = new HashMap<>(); |
| 53 | +channelOpts.params.put("echo", "false"); |
| 54 | +
|
| 55 | +Channel channel = ably.channels.get("{{RANDOM_CHANNEL_NAME}}", channelOpts); |
| 56 | +
|
| 57 | +channel.subscribe(new Channel.MessageListener() { |
| 58 | + @Override |
| 59 | + public void onMessage(Message message) { |
| 60 | + // Only receives messages from other clients, not from this client |
| 61 | + System.out.println("Received: " + message.data); |
| 62 | + } |
| 63 | +}); |
| 64 | +``` |
| 65 | + |
| 66 | +```realtime_go |
| 67 | +channel := realtime.Channels.Get("{{RANDOM_CHANNEL_NAME}}", ably.ChannelWithParams("echo", "false")) |
| 68 | +
|
| 69 | +_, err := channel.SubscribeAll(context.Background(), func(msg *ably.Message) { |
| 70 | + // Only receives messages from other clients, not from this client |
| 71 | + log.Println("Received:", msg.Data) |
| 72 | +}) |
| 73 | +if err != nil { |
| 74 | + log.Panic(err) |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +```realtime_flutter |
| 79 | +final channel = realtime.channels.get('{{RANDOM_CHANNEL_NAME}}'); |
| 80 | +const channelOptions = RealtimeChannelOptions( |
| 81 | + params: {'echo': 'false'}, |
| 82 | +); |
| 83 | +
|
| 84 | +await channel.setOptions(channelOptions); |
| 85 | +channel.subscribe().listen((message) { |
| 86 | + // Only receives messages from other clients, not from this client |
| 87 | + print('Received: ${message.data}'); |
| 88 | +}); |
| 89 | +``` |
| 90 | +</Code> |
| 91 | + |
| 92 | +## Interaction with connection-level echo <a id="connection-level"/> |
| 93 | + |
| 94 | +The channel-level `echo` param works alongside the connection-level [`echoMessages`](/docs/api/realtime-sdk/types#client-options) setting: |
| 95 | + |
| 96 | +| Connection `echoMessages` | Channel `echo` param | Result | |
| 97 | +|---------------------------|---------------------|--------| |
| 98 | +| `true` (default) | Not set | Messages echoed | |
| 99 | +| `true` (default) | `false` | Messages suppressed on this channel | |
| 100 | +| `false` | Not set | Messages suppressed (connection-level) | |
| 101 | +| `false` | `false` | Messages suppressed | |
| 102 | + |
| 103 | +The channel-level param only adds suppression. If the connection already has `echoMessages` set to `false`, echo is suppressed regardless of the channel param. |
| 104 | + |
| 105 | +<Aside data-type='note'> |
| 106 | +The `echo` channel param only affects messages. Presence events are always delivered regardless of the echo setting. |
| 107 | +</Aside> |
0 commit comments