概述: 用Go在whisper中监听/订阅消息的教程。

监听/订阅Whisper消息

在本节中,我们将订阅websockets上的Whisper消息。 我们首先需要的是一个通道,它将从whisper/whisperv6包中的Message类型接收Whispe消息。

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

在我们调用订阅之前,我们首先需要确定消息的过滤标准。 从whisperv6包中初始化一个新的Criteria对象。 由于我们只对定位到我们的消息感兴趣,因此我们将条件对象上的PrivateKeyID属性设置为我们用于加密消息的相同密钥ID。

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

接下来,我们调用客户端的SubscribeMessages方法,该方法订阅符合给定条件的消息。 HTTP不支持此方法; 仅支持双向连接,例如websockets和IPC。 最后一个参数是我们之前创建的消息通道。

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

现在我们已经订阅了,我们可以使用select语句来读取消息,并处理订阅中的错误。 如果您从上一节回忆起来,消息内容在Payload属性中作为字节切片,我们可以将其转换回人类可读的字符串。

  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. }

查看下面的完整代码,获取完整的栗子。 这就是消息订阅的所有内容。

完整代码

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. }