GoGo V4 SDK v4.9.1

This page outlines the steps to follow to create a simple Hello, World application with PubNub. This covers the basics of integrating PubNub in your application: setting up a connection to PubNub, and sending and receiving messages.

SDK getting startedSample app quickstart
  1. PubNub account
  2. Download the SDK
  3. Send messages
  • n/a

Sign in or create an account to create an app on the Admin Portal and get the keys to use in your application.

When you create a new app, the first set of keys is generated automatically, but a single app can have as many keysets as you like. We recommend that you create separate keysets for production and test environments.

Download the SDK

Download the SDK from any of the following sources:

Use go

To integrate PubNub into your project using the go command:

go get github.com/pubnub/go

If you encounter dependency issues, use the dep ensure command to resolve them.

Get the source code

View the supported platforms here.

Configure PubNub

In the IDE of your choice, create a new App file and add the following code. This is the minimum configuration you need to send and receive messages with PubNub.

Make sure to replace myPublishKey and mySubscribeKey with your app's publish and subscribe keys from the Admin Portal.

func main() {
    config := pubnub.NewConfig()
    config.SubscribeKey = "mySubscribeKey"
    config.PublishKey = "myPublishKey"
    config.UUID = "myUniqueUUID"

    pn := pubnub.NewPubNub(config)
}

For more information, refer to the Configuration section of the SDK documentation.

Listeners help your app react to events and messages. You can implement custom app logic to respond to each type of message or event.

Copy the code below to configure your app such that when it receives a message, the content of the message is printed.

listener := pubnub.NewListener()
doneConnect := make(chan bool)
donePublish := make(chan bool)

msg := map[string]interface{}{
    "msg": "Hello world",
}
go func() {
    for {
        select {
        case status := <-listener.Status:
            switch status.Category {
            case pubnub.PNDisconnectedCategory:
                // This event happens when radio / connectivity is lost
            case pubnub.PNConnectedCategory:
                // Connect event. You can do stuff like publish, and know you'll get it.
                // Or just use the connected event to confirm you are subscribed for
                // UI / internal notifications, etc
                doneConnect <- true
            case pubnub.PNReconnectedCategory:
                // Happens as part of our regular operation. This event happens when
                // radio / connectivity is lost, then regained.
            }
        case message := <-listener.Message:
            // Handle new message stored in message.message
            if message.Channel != "" {
                // Message has been received on channel group stored in
                // message.Channel
            } else {
                // Message has been received on channel stored in
                // message.Subscription
            }
            if msg, ok := message.Message.(map[string]interface{}); ok {
                fmt.Println(msg["msg"])
            }
            /*
                log the following items with your favorite logger
                    - message.Message
                    - message.Subscription
                    - message.Timetoken
            */

            donePublish <- true
        case <-listener.Presence:
            // handle presence
        }
    }
}()

pn.AddListener(listener)

For more information, refer to the Listeners section of the SDK documentation.

To receive messages sent to a particular channel, you subscribe to it. When you publish a message to a channel, PubNub delivers that message to everyone subscribed to that channel.

In this app, publishing a message is triggered when the subscribe call is finished successfully. The Publish() method uses the msg variable that you can see in the code below.

To subscribe, you send a subscribe call.

msg := map[string]interface{}{
        "msg": "Hello world!"
}

pn.Subscribe().
    Channels([]string{"hello_world"}).
    Execute()

<-doneConnect

response, status, err := pn.Publish().
    Channel("hello_world").Message(msg).Execute()

if err != nil {
     // Request processing failed.
     // Handle message publish error
}

For more information, refer to the Publish and Subscribe section of the SDK documentation, and to Publishing a Message.

Your App file should now look similar to the following:

import (
    "fmt"

    pubnub "github.com/pubnub/go"
)

func main() {
    config := pubnub.NewConfig()
    config.SubscribeKey = "demo"
    config.PublishKey = "demo"
    config.UUID = "myUniqueUUID"

    pn := pubnub.NewPubNub(config)
    listener := pubnub.NewListener()
    doneConnect := make(chan bool)
    donePublish := make(chan bool)

    msg := map[string]interface{}{
        "msg": "Hello worlds",
    }
    go func() {
        for {
            select {
            case status := <-listener.Status:
                switch status.Category {
                case pubnub.PNDisconnectedCategory:
                    // This event happens when radio / connectivity is lost
                case pubnub.PNConnectedCategory:
                    // Connect event. You can do stuff like publish, and know you'll get it.
                    // Or just use the connected event to confirm you are subscribed for
                    // UI / internal notifications, etc
                    doneConnect <- true
                case pubnub.PNReconnectedCategory:
                    // Happens as part of our regular operation. This event happens when
                    // radio / connectivity is lost, then regained.
                }
            case message := <-listener.Message:
                // Handle new message stored in message.message
                if message.Channel != "" {
                    // Message has been received on channel group stored in
                    // message.Channel
                } else {
                    // Message has been received on channel stored in
                    // message.Subscription
                }
                if msg, ok := message.Message.(map[string]interface{}); ok {
                    fmt.Println(msg["msg"])
                }
                /*
                    log the following items with your favorite logger
                        - message.Message
                        - message.Subscription
                        - message.Timetoken
                */

                donePublish <- true
            case <-listener.Presence:
                // handle presence
            }
        }
    }()

    pn.AddListener(listener)

    pn.Subscribe().
       Channels([]string{"hello_world"}).
       Execute()

    <-doneConnect

    response, status, err := pn.Publish().
        Channel("hello_world").Message(msg).Execute()

    if err != nil {
        // Request processing failed.
        // Handle message publish error
    }

    fmt.Println(response, status, err)

    <-donePublish
}

Now, run your app to see if you did everything correctly. You should see "Hello world" printed in the console.

Congratulations! You've just subscribed to a channel and sent your first message.

Instead of focusing on the order in which you wrote the code, let's focus on the order in which it runs. The app you just created does a few things:

  • configures a PubNub connection
  • adds the status, message, and presence event listeners
  • subscribes to a channel
  • publishes a message

The following code is the minimum configuration you need to send and receive messages with PubNub. For more information, refer to the Configuration section of the SDK documentation.

func main() {
    config := pubnub.NewConfig()
    config.SubscribeKey = "mySubscribeKey"
    config.PublishKey = "myPublishKey"
    config.UUID = "myUniqueUUID"

    pn := pubnub.NewPubNub(config)
}

Listeners help your app react to events and messages. You can implement custom app logic to respond to each type of message or event.

You added three listeners to the app: status, message, and presence. Status listens for status events and presence listens for presence events, but in this case, both listeners are a no operation implementations. The remaining listener, message, listens for incoming messages on a particular channel. When it receives a message, the app simply prints the received message. This is why you see "Hello world" displayed in the console.

listener := pubnub.NewListener()
doneConnect := make(chan bool)
donePublish := make(chan bool)

msg := map[string]interface{}{
    "msg": "Hello world",
}
go func() {
    for {
        select {
        case status := <-listener.Status:
            switch status.Category {
            case pubnub.PNDisconnectedCategory:
                // This event happens when radio / connectivity is lost
            case pubnub.PNConnectedCategory:
                // Connect event. You can do stuff like publish, and know you'll get it.
                // Or just use the connected event to confirm you are subscribed for
                // UI / internal notifications, etc
                doneConnect <- true
            case pubnub.PNReconnectedCategory:
                // Happens as part of our regular operation. This event happens when
                // radio / connectivity is lost, then regained.
            }
        case message := <-listener.Message:
            // Handle new message stored in message.message
            if message.Channel != "" {
                // Message has been received on channel group stored in
                // message.Channel
            } else {
                // Message has been received on channel stored in
                // message.Subscription
            }
            if msg, ok := message.Message.(map[string]interface{}); ok {
                fmt.Println(msg["msg"])
            }
            /*
                log the following items with your favorite logger
                    - message.Message
                    - message.Subscription
                    - message.Timetoken
            */

            donePublish <- true
        case <-listener.Presence:
            // handle presence
        }
    }
}()

pn.AddListener(listener)

For more information, refer to the Listeners section of the SDK documentation.

PubNub uses the Publish/Subscribe model for realtime communication. This model involves two essential parts:

  • Channels are transient paths over which your data is transmitted
  • Messages contain the data you want to transmit to one or more recipients

When you want to receive messages sent to a particular channel, you subscribe to it. When you publish a message to a channel, PubNub delivers that message to everyone who is subscribed to that channel. In this example, you subscribe to a channel named hello_world.

A message can be any type of JSON-serializable data (such as objects, arrays, integers, strings) that is smaller than 32 KiB. PubNub will, in most cases, deliver your message to its intended recipients in fewer than 100 ms regardless of their location. You can also share files up to 5MB.

When your app successfully connects to a channel, it calls the Publish() method, which sends the "Hello world" message.

msg := map[string]interface{}{
        "msg": "Hello world!"
}

response, status, err := pn.Publish().
    Channel("hello_world").Message(msg).Execute()

if err != nil {
     // Request processing failed.
     // Handle message publish error
}

You can subscribe to more than one channel with a single subscribe call but in this example, you subscribe to a single channel:

pn.Subscribe().
    Channels([]string{"hello_world"}).
    Execute()

For more information, refer to the Publish and Subscribe section of the SDK documentation, and to Publishing a Message.

You have just learned how to use the Go SDK to send and receive messages using PubNub. Next, take a look at the SDK's reference documentation, which covers PubNub API in more detail.