go-waku/docs/relay.md

4.2 KiB
Raw Blame History

Receive and send messages using Waku Relay

Waku Relay is a gossip protocol that enables you to send and receive messages. You can find Waku Relays specifications on Vac RFC.

Create a waku instance

package main

import (
	"context"
    "fmt"

	"github.com/status-im/go-waku/waku/v2/node"
	"github.com/status-im/go-waku/waku/v2/protocol/relay"
)

...
wakuNode, err := node.New(context.Background(),
    node.WithWakuRelay(),
)
if err != nil {
    fmt.Println(err)
    return
}

if err := wakuNode.Start(); err != nil {
    fmt.Println(err)
    return
}
...

Options

One of these options must be specified when instantiating a node supporting the waku relay protocol

  • WithWakuRelay(opts ...pubsub.Option) - enables the waku relay protocol and receives an optional list of pubsub options to tune or configure the gossipsub parameters. Supported options can be seen here. The recommended parameter configuration is used by default.
  • WithWakuRelayAndMinPeers(minRelayPeersToPublish int, opts ...pubsub.Option) - enables the waku relay protocol, specifying the minimum number of peers a topic should have to send a message. It also receives an optional list of pubsub options

Receiving messages

...
sub, err := wakuNode.Relay().Subscribe(context.Background())
if err != nil {
    fmt.Println(err)
    return
}

for value := range sub.C {
    fmt.Println("Received msg:", string(value.Message().Payload))
}
...

To receive messages sent via the relay protocol, you need to subscribe to a pubsub topic. This can be done via any of these functions:

  • wakuNode.Relay().Subscribe(ctx) - subscribes to the default waku pubsub topic /waku/2/default-waku/proto
  • wakuNode.Relay().SubscribeToTopic(ctx, topic) - subscribes to a custom pubsub topic

These functions return a Subscription struct containing a channel on which messages will be received. To stop receiving messages in this channel sub.Unsubscribe() can be executed which will close the channel (without unsubscribing from the pubsub topic)

Pubsub topics should follow the recommended usage structure. For this purpose, the NewPubsubTopic helper function was created:

import 	"github.com/status-im/go-waku/waku/v2/protocol"

topic := protocol.NewPubsubTopic("the_topic_name", "the_encoding")
/*
fmt.Println(topic.String())  // => `/waku/2/the_topic_name/the_encoding`
*/

Sending messages

import (
    "github.com/status-im/go-waku/waku/v2/protocol/pb"
    "github.com/status-im/go-waku/waku/v2/utils"
)

...
msg := &pb.WakuMessage{
    Payload:      []byte("Hello World"),
    Version:      0,
    ContentTopic: protocol.NewContentTopic("basic2", 1, "test", "proto").String(),
    Timestamp:    utils.GetUnixEpoch(),
}

msgId, err = wakuNode.Relay().Publish(context.Background(), msg)
if err != nil {
    log.Error("Error sending a message: ", err)
}

To send a message, it needs to be wrapped into a WakuMessage protobuffer. The payload of the message is not limited to strings. Any kind of data that can be serialized into a []byte can be sent as long as it does not exceed the maximum length a message can have (~1MB)

The following functions can be used to publish a message:

  • wakuNode.Relay().Publish(ctx, msg) - to send a message to the default waku pubsub topic
  • wakuNode.Relay().PublishToTopic(ctx, msg, topic) - to send a message to a custom pubsub topic

Both of these functions will return a message id on success, or an error if the message could not be published.

If WithWakuRelayAndMinPeers was used during the instantiation of the wakuNode, it should be possible to verify if there's enough peers for publishing to a topic with wakuNode.Relay().EnoughPeersToPublish() and wakuNode.Relay().EnoughPeersToPublishToTopic(topic)

Stop receiving messages

...
err := wakuNode.Relay().Unsubscribe(context.Background(), theTopic)
if err != nil {
    fmt.Println(err)
    return
}
...

To stop receiving messages from the default topic, use relay.DefaultWakuTopic as the topic parameter