# Basic pub-sub
Ably Pub/Sub enables you to implement the publish-subscribe (pub-sub) pattern. Any number of publishers can send messages to a channel, and any number of subscribers can receive those messages. Publishers and subscribers are completely decoupled from one another.
[Channels](https://ably.com/docs/channels) are used to separate messages into different topics. [Messages](https://ably.com/docs/messages) contain the data that a client is communicating, such as the contents of an individual chat message, or an event that has occurred, such as updated financial information. Whilst billions of messages may be delivered by Ably, clients receive only the messages on the channels they subscribe to.
To get started with sending and receiving messages, all you need to do is:
* [Use a channel](#use)
* [Subscribe to the channel](#subscribe)
* [Publish messages to the channel](#publish)
## Use a channel
Channels are used to separate your message traffic into different topics, and are identified by a unique name. Clients create or retrieve a channel and can then subscribe to them, and send messages to them.
Use the [`get()`](https://ably.com/docs/api/realtime-sdk/channels#get) method to create or retrieve a channel instance:
```realtime_javascript
const channel = realtime.channels.get('your-channel-name');
```
```realtime_nodejs
const channel = realtime.channels.get('your-channel-name');
```
```realtime_java
Channel channel = realtime.channels.get("your-channel-name");
```
```realtime_csharp
IRealtimeChannel channel = realtime.Channels.Get("your-channel-name"); realtime
```
```realtime_ruby
channel = realtime.channels.get('your-channel-name') realtime
```
```realtime_python
channel = realtime.channels.get('your-channel-name')
```
```realtime_objc
ARTRealtimeChannel *channel = [realtime.channels get:@"your-channel-name"];
```
```realtime_swift
let channel = realtime.channels.get("your-channel-name")
```
```realtime_flutter
final channel = realtime.channels.get('your-channel-name');
```
```realtime_go
channel := realtime.Channels.Get("your-channel-name")
```
```rest_javascript
const channel = rest.channels.get('your-channel-name');
```
```rest_nodejs
const channel = rest.channels.get('your-channel-name');
```
```rest_java
Channel channel = rest.channels.get("your-channel-name");
```
```rest_csharp
Channel channel = rest.Channels.Get("your-channel-name"); rest
```
```rest_ruby
channel = rest.channels.get('your-channel-name') rest
```
```rest_python
channel = rest.channels.get('your-channel-name')
```
```rest_php
$channel = $rest->channels->get('your-channel-name');
```
```rest_objc
ARTRestChannel *channel = [realtime.channels get:@"your-channel-name"];
```
```rest_swift
let channel = realtime.channels.get("your-channel-name")
```
```rest_flutter
final channel = rest.channels.get('your-channel-name');
```
```rest_go
channel := rest.Channels.Get("your-channel-name")
```
## Subscribe to a channel
Clients subscribe to a channel to receive the messages published to it. Clients can subscribe to all messages, or only messages identified by specific names.
Subscribing is an operation that is only available to the realtime interface of Pub/Sub SDKs. This is because it requires establishing a persistent [connection](https://ably.com/docs/connect) to Ably in order to receive messages in realtime.
Use the [`subscribe()`](https://ably.com/docs/api/realtime-sdk/channels#subscribe) method on a channel to receive any messages that are published to it.
The following is an example of subscribing to all messages on a channel:
```realtime_javascript
const realtime = new Ably.Realtime('your-api-key');
const channel = realtime.channels.get('your-channel-name');
await channel.subscribe((message) => {
alert('Received: ' + message.data);
});
```
```realtime_nodejs
const realtime = new Ably.Realtime('your-api-key');
const channel = realtime.channels.get('your-channel-name');
await channel.subscribe((message) => {
console.log("Received: " + message.data);
});
```
```realtime_ruby
realtime = Ably::Realtime.new('your-api-key')
channel = realtime.channels.get('your-channel-name')
channel.subscribe do |message|
puts "Received: #{message.data}"
end
```
```realtime_python
realtime = AblyRealtime('your-api-key')
channel = realtime.channels.get('your-channel-name')
def listener(message):
print('Received ' + message.data)
await channel.subscribe(listener)
```
```realtime_java
AblyRealtime realtime = new AblyRealtime("your-api-key");
Channel channel = realtime.channels.get("your-channel-name");
channel.subscribe(new MessageListener() {
@Override
public void onMessage(Message message) {
System.out.println("New messages arrived. " + message.name);
}
});
```
```realtime_csharp
AblyRealtime realtime = new AblyRealtime("your-api-key");
IRealtimeChannel channel = realtime.Channels.Get("your-channel-name");
channel.Subscribe(message => {
Console.WriteLine($"Message: {message.Name}:{message.Data} received");
});
```
```realtime_objc
ARTRealtime *realtime = [[ARTRealtime alloc] initWithKey:@"your-api-key"];
ARTRealtimeChannel *channel = [realtime.channels get:@"your-channel-name"];
[channel subscribe:^(ARTMessage *message) {
NSLog(@"Received: %@", message.data);
}];
```
```realtime_swift
let realtime = ARTRealtime(key: "your-api-key")
let channel = realtime.channels.get("your-channel-name")
channel.subscribe { message in
print("Received: \(message.data)")
}
```
```realtime_flutter
final realtime = ably.Realtime(key: 'your-api-key');
final channel = realtime.channels.get('your-channel-name');
final channelMessageSubscription = channel
.subscribe()
.listen((ably.Message message) {
print('Received: ${message.data}');
}
);
```
```realtime_go
realtime, err := ably.NewRealtime(
ably.WithKey("your-api-key"))
channel := realtime.Channels.Get("your-channel-name")
if err != nil {
panic(err)
}
_, err = channel.SubscribeAll(context.Background(), func(msg *ably.Message) {
fmt.Printf("Received: '%v'\n", msg.Data)
})
```
The following is an example of only subscribing to messages with a specific name:
```realtime_javascript
await channel.subscribe('myEvent', (message) => {
console.log('message received for event ' + message.name);
console.log('message data:' + message.data);
});
```
```realtime_nodejs
await channel.subscribe('myEvent', (message) => {
console.log('message received for event ' + message.name);
console.log('message data:' + message.data);
});
```
```realtime_java
channel.subscribe("myEvent", new MessageListener() {
@Override
public void onMessage(Message message) {
System.out.println("Message received: " + message.data);
}
});
```
```realtime_csharp
channel.Subscribe("myEvent", message =>
{
Console.WriteLine($"message received for event {message.Name}");
Console.WriteLine($"message data: {message.Data}");
});
```
```realtime_ruby
channel.subscribe('myEvent') do |message|
puts "message received for event #{message.name}"
puts "message data: #{message.data}"
end
```
```realtime_python
realtime = AblyRealtime('your-api-key')
channel = realtime.channels.get('your-channel-name')
def listener(message):
print(f'Message received for {message.name}: {message.data}')
await channel.subscribe('myEvent', listener)
```
```realtime_swift
channel.subscribe("myEvent") { message in
print("message received for event \(message.name)")
print("message data: \(message.data)")
}
```
```realtime_objc
[channel subscribe:@"myEvent" callback:^(ARTMessage *message) {
NSLog(@"message received for event %@", message.name);
NSLog(@"message data: %@", message.data);
}];
```
```realtime_flutter
final channelMessageSubscription = channel
.subscribe(name: 'myEvent')
.listen((ably.Message message) {
print('message received for event ${message.name}');
print('message data: ${message.data}');
}
);
```
```realtime_go
_, err = channel.Subscribe(context.Background(), "myEvent", func(msg *ably.Message) {
fmt.Printf("message received for event: '%v'\n", msg.Name)
fmt.Printf("message data: '%v'\n", msg.Data)
})
```
## Publish a message
Publishing messages to a channel is how clients communicate with one another. Any subscribers will receive published messages as long as they are subscribed and have the `subscribe` [capability](https://ably.com/docs/auth/capabilities) for that channel.
Publishing is an operation available to the realtime and REST interfaces of Pub/Sub SDKs. REST publishing is more efficient if you don't need to establish a persistent [connection](https://ably.com/docs/connect) to Ably, such as to subscribe to messages. For example, if you have a server publishing messages to channels that doesn't need to receive any updates from them.
Use the [`publish()`](https://ably.com/docs/api/realtime-sdk/channels#publish) method to send messages to a channel.
```realtime_javascript
const realtime = new Ably.Realtime('your-api-key');
const channel = realtime.channels.get('your-channel-name');
await channel.publish('example', 'message data');
```
```realtime_nodejs
const realtime = new Ably.Realtime('your-api-key');
const channel = realtime.channels.get('your-channel-name');
await channel.publish('example', 'message data');
```
```realtime_ruby
realtime = Ably::Realtime.new('your-api-key')
channel = realtime.channels.get('your-channel-name')
channel.publish 'example', 'message data'
```
```realtime_python
# Python realtime currently utilizes a REST publish
realtime = AblyRealtime('your-api-key')
channel = realtime.channels.get('your-channel-name')
await channel.publish('example', 'message data')
```
```realtime_java
AblyRealtime realtime = new AblyRealtime("your-api-key");
Channel channel = realtime.channels.get("your-channel-name");
channel.publish("example", "message data");
```
```realtime_csharp
AblyRealtime realtime = new AblyRealtime("your-api-key");
IRealtimeChannel channel = realtime.Channels.Get("your-channel-name");
channel.Publish("example", "message data");
```
```realtime_objc
ARTRealtime *realtime = [[ARTRealtime alloc] initWithKey:@"your-api-key"];
ARTRealtimeChannel *channel = [realtime.channels get:@"your-channel-name"];
[channel publish:@"example" data:@"message data"];
```
```realtime_swift
let realtime = ARTRealtime(key: "your-api-key")
let channel = realtime.channels.get("your-channel-name")
channel.publish("example", data: "message data")
```
```realtime_flutter
final realtime = ably.Realtime(key: 'your-api-key');
final channel = realtime.channels.get('your-channel-name');
await channel.publish(name: 'example', data: 'message data');
```
```realtime_go
realtime, err := ably.NewRealtime(
ably.WithKey("your-api-key"))
if err != nil {
log.Fatalf("Error creating Ably client: %v", err)
}
channel := realtime.Channels.Get("your-channel-name")
channel.Publish(context.Background(), "example", "message data")
```
```rest_javascript
const rest = new Ably.Rest('your-api-key');
const channel = rest.channels.get('your-channel-name');
await channel.publish('example', 'message data');
```
```rest_nodejs
const rest = new Ably.Rest('your-api-key');
const channel = rest.channels.get('your-channel-name');
await channel.publish('example', 'message data');
```
```rest_ruby
rest = Ably::Rest.new('your-api-key')
channel = rest.channels.get('your-channel-name')
channel.publish 'example', 'message data'
```
```rest_python
rest = AblyRest('your-api-key')
channel = rest.channels.get('your-channel-name')
await channel.publish(u'example', u'message data')
```
```rest_php
$rest = new Ably\AblyRest('your-api-key');
$channel = $rest->channels->get('your-channel-name');
$channel->publish('example', 'message data');
```
```rest_java
AblyRest rest = new AblyRest("your-api-key");
Channel channel = rest.channels.get("your-channel-name");
channel.publish("example", "message data");
```
```rest_csharp
AblyRest rest = new AblyRest("your-api-key");
var channel = rest.Channels.Get("your-channel-name");
await channel.PublishAsync("example", "message data");
```
```rest_objc
ARTRest *rest = [[ARTRest alloc] initWithKey:@"your-api-key"];
ARTRestChannel *channel = [rest.channels get:@"your-channel-name"];
[channel publish:@"example" data:@"message data"];
```
```rest_swift
let rest = ARTRest(key: "your-api-key")
let channel = rest.channels.get("your-channel-name")
channel.publish("example", data: "message data")
```
```rest_flutter
final rest = ably.Rest('your-api-key');
final channel = rest.channels.get('your-channel-name');
channel.publish(name: 'example', data: 'message data');
```
```rest_go
rest, err := ably.NewREST(
ably.WithKey("your-api-key"))
if err != nil {
panic(err)
}
channel := rest.Channels.Get("your-channel-name")
if err := channel.Publish(context.Background(), "example", "message data"); err != nil {
panic(err)
}
```