# 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) } ```