JSON 数据作为 PubSub 的消息

Posted

技术标签:

【中文标题】JSON 数据作为 PubSub 的消息【英文标题】:JSON data as message for PubSub 【发布时间】:2021-01-23 09:36:30 【问题描述】:

我根据谷歌“将消息发布到主题”指南编写了以下代码:

import (
        "context"
        "fmt"
        "io"
        "cloud.google.com/go/pubsub"
)

func publishMessage(w io.Writer, projectID, topicID) error 
        msg := `
                  "source":"test_source",
                  "data": 
                          "jobId": "123",
                          "recordCount": 10000
                          
                `
        ctx := context.Background()
        client, err := pubsub.NewClient(ctx, projectID)
        if err != nil 
                return fmt.Errorf("pubsub.NewClient: %v", err)
        

        t := client.Topic(topicID)

        result := t.Publish(ctx, &pubsub.MessageData: []byte(msg))
        id, err := result.Get(ctx)
        if err != nil 
                return fmt.Errorf("Get: %v", err)
        
        fmt.Fprintf(w, "Published a message; msg ID: %v\n", id)
        return nil


但每次我在 Cloud Function 的日志中收到错误时:

“com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 应为 BEGIN_OBJECT,但为 STRING”

如果您对如何解决此问题有任何想法,我将不胜感激。

订阅交付类型:推送

云函数触发器:主题

【问题讨论】:

【参考方案1】:

这不是真正的 Go 问题,而是 NodeJS 问题。尽管问题完全缺少 Cloud Function 的代码,但我仍然可以看出它有什么问题:由于您推送的是字符串而不是 JSON,因此您必须使用 JSON.parse(string); 才能在其上使用 GSON。


如果你想要一个 Go 答案,你可能需要推送 JSON,开始。

在 Go 中,可以使用 json.Marshal() 编码 JSON(data object 可以定义为 struct):

type Message struct 
    source string
    data object

msg := Message ... 
payload, err := json.Marshal(msg)

在哪一端解决通过推送 JSON 字符串而不是 JSON 而产生的问题并不重要。第二种方法可能比第一种方法好一点(就已经提供了预期的格式而言,而不是稍后搞砸)。这是基于,JSON 和 JSON 字符串不是同一个东西(甚至不是相同的内容)。

【讨论】:

以上是关于JSON 数据作为 PubSub 的消息的主要内容,如果未能解决你的问题,请参考以下文章

Pub/Sub 推送消息没有 messageId 属性

通过http请求将Google pubsub作为JSON发布

GCP - 从 PubSub 到 BigQuery 的消息

在 Dataflow Python 中从 PubSub 读取 AVRO 消息

云功能不向 PubSub 发送消息

Bigquery 使用数据流发布订阅消息推送