4.2 KiB
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 Relay’s 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 topicwakuNode.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 withwakuNode.Relay().EnoughPeersToPublish()
andwakuNode.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