description: Tutorial on how to subscribe to messages on whisper with Go.

Subscribing to Whisper Messages

In this section we’ll be subscribing to whisper messages over websockets. First thing we need is a channel that will be receiving whisper messages in the Message type from the whisper/whisperv6 package.

  1. messages := make(chan *whisperv6.Message)

Before we invoke a subscription, we first need to determine the criteria. From the whisperv6 package initialize a new Criteria object. Since we’re only interested in messages targeted to us, we’ll set the PrivateKeyID property on the criteria object to the same key ID we used for encrypting messages.

  1. criteria := whisperv6.Criteria{
  2. PrivateKeyID: keyID,
  3. }

Next we invoke the client’s SubscribeMessages method which subscribes to messages that match the given criteria. This method is not supported over HTTP; only supported on bi-directional connections such as websockets and IPC. The last argument is the messages channel we created earlier.

  1. sub, err := client.SubscribeMessages(context.Background(), criteria, messages)
  2. if err != nil {
  3. log.Fatal(err)
  4. }

Now that we have our subscription, we can use a select statement to read messages as they come in and also to handle errors from the subscription. If you recall from the previous section, the message content is in the Payload property as a byte slice which we can convert back to a human readable string.

  1. for {
  2. select {
  3. case err := <-sub.Err():
  4. log.Fatal(err)
  5. case message := <-messages:
  6. fmt.Printf(string(message.Payload)) // "Hello"
  7. }
  8. }

Check out the full code below for a complete working example. That’s all there is to whisper message subscriptions.

Full code

Commands

  1. geth --shh --rpc --ws

whisper_subscribe.go

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "os"
  7. "runtime"
  8. "github.com/ethereum/go-ethereum/common/hexutil"
  9. "github.com/ethereum/go-ethereum/whisper/shhclient"
  10. "github.com/ethereum/go-ethereum/whisper/whisperv6"
  11. )
  12. func main() {
  13. client, err := shhclient.Dial("ws://127.0.0.1:8546")
  14. if err != nil {
  15. log.Fatal(err)
  16. }
  17. keyID, err := client.NewKeyPair(context.Background())
  18. if err != nil {
  19. log.Fatal(err)
  20. }
  21. fmt.Println(keyID) // 0ec5cfe4e215239756054992dbc2e10f011db1cdfc88b9ba6301e2f9ea1b58d2
  22. messages := make(chan *whisperv6.Message)
  23. criteria := whisperv6.Criteria{
  24. PrivateKeyID: keyID,
  25. }
  26. sub, err := client.SubscribeMessages(context.Background(), criteria, messages)
  27. if err != nil {
  28. log.Fatal(err)
  29. }
  30. go func() {
  31. for {
  32. select {
  33. case err := <-sub.Err():
  34. log.Fatal(err)
  35. case message := <-messages:
  36. fmt.Printf(string(message.Payload)) // "Hello"
  37. os.Exit(0)
  38. }
  39. }
  40. }()
  41. publicKey, err := client.PublicKey(context.Background(), keyID)
  42. if err != nil {
  43. log.Print(err)
  44. }
  45. fmt.Println(hexutil.Encode(publicKey)) // 0x04f17356fd52b0d13e5ede84f998d26276f1fc9d08d9e73dcac6ded5f3553405db38c2f257c956f32a0c1fca4c3ff6a38a2c277c1751e59a574aecae26d3bf5d1d
  46. message := whisperv6.NewMessage{
  47. Payload: []byte("Hello"),
  48. PublicKey: publicKey,
  49. TTL: 60,
  50. PowTime: 2,
  51. PowTarget: 2.5,
  52. }
  53. messageHash, err := client.Post(context.Background(), message)
  54. if err != nil {
  55. log.Fatal(err)
  56. }
  57. fmt.Println(messageHash) // 0xdbfc815d3d122a90d7fb44d1fc6a46f3d76ec752f3f3d04230fe5f1b97d2209a
  58. runtime.Goexit() // wait for goroutines to finish
  59. }