使用 GCloud 模拟器的 Google Cloud PubSub V1

Posted

技术标签:

【中文标题】使用 GCloud 模拟器的 Google Cloud PubSub V1【英文标题】:Google Cloud PubSub V1 using GCloud Emulator 【发布时间】:2019-03-14 11:09:45 【问题描述】:

我正在与 Google Docs 争夺使用 PubSub 模拟器通过 .NET 设置 Cloud PubSub。

https://cloud.google.com/dotnet/docs/getting-started/using-pub-sub

https://cloud.google.com/pubsub/docs/publisher

https://cloud.google.com/pubsub/docs/emulator

来自 Rails 背景,我的任务是为 .NET 产品实现 Cloud PubSub,在 .NET Core 上运行我们的谷歌云,使其能够发布。

Google::Cloud::Pubsub.new(project: project_id, emulator_host: emulator_host)

从使用 .NET 的文档中,我不断回到以下内容:

PublisherServiceApiClient publisherClient = PublisherServiceApiClient.Create();
PublisherClient publisher = PublisherClient.Create(...)

但是,文档Google.Cloud.PubSub.V1 -Pre 中使用的库不包含定义。

'PublisherClient' does not contain a definition for 'Create'

相反,我得到了CreateAsync,它包含TopicNamePublisherClient.ClientCreationSettingsPublisherClient.Settings

https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/api/Google.Cloud.PubSub.V1.PublisherClient.html

我注意到PublisherServiceApiClient 可以接收Channel,但我对如何实现这一点感到困惑。

以一个实际问题结束,目前如何在云中使用 .NET 实现 Cloud PubSub,然后使用模拟器在本地实现?除此之外,我是否使用了错误的库或错误的文档?

任何建议、指点或建议将不胜感激。

【问题讨论】:

这是有据可查的东西,可能太多了。。搜索后我找到了这个教程,它指导你如何设置你的开发环境。cloud.google.com/appengine/docs/flexible/dotnet/… 至于为什么你的 Create() 没有显示,可能是您缺少设置步骤.. 不幸的是,该指南适用于 ASP.NET 应用程序,而我们的应用程序不是:/ 我认为该指南可能有一些内容,但似乎他们也在使用 PublisherClient.Create()。 .. 我认为他们在 HelloWorld 教程中使用了 ASP .Net Core.. 还有更大的 Bookshelf 应用程序包罗万象的教程(可能也不是你想要的)cloud.google.com/dotnet/docs/getting-started/tutorial-app 是的,我最初是在使用 Bookshelf 应用教程,但同样的问题。 对于PublisherClient,您确实应该使用CreateAsync。我们目前没有任何直接的仿真器支持,尽管正在进行的工作可能会使这更简单。你可以指定一个PublisherClient.ClientCreationSettings 和一个合适的ServiceEndpointChannelCredentials.Insecure 来与模拟器对话。目前我不会为这个问题添加答案,因为这不是一个明确的问题to 答案 - 有些部分似乎是关于文档的,有些是关于创建的,还有一些是关于模拟器的。如果您可以针对特定问题澄清这一点,则添加答案会更容易。 【参考方案1】:

我管理了一个我很满意的解决方案。

我没有使用PublisherClient,而是单独使用PublisherServiceApiClient

emulatorAddr = Environment.GetEnvironmentVariable("PUBSUB_EMULATOR_HOST");
if (emulatorAddr != null)

    channel = new Channel(emulatorAddr, ChannelCredentials.Insecure);
    pub = PublisherServiceApiClient.Create(channel);

else

    pub = PublisherServiceApiClient.Create();

这意味着发布比将字符串发送到PublisherClient 稍微复杂一些,但总体来说还不错。

PubsubMessage msg = new PubsubMessage

    Data = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(payload))
;

pub.PublishAsync(topic, new[] msg );

如果项目在 Google Compute Engine 中运行,它将具有默认凭据。否则,无论您是在本地运行模拟器还是在 docker 中运行,您都可以定义 PUBSUB_EMULATOR_HOST

真正有帮助的是https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.PubSub.V1/index.html

【讨论】:

【参考方案2】:

要使PublisherClient 连接到本地模拟器,您需要将自定义ServiceEndpointChannelCredentials 传递给CreateAsync

var serviceEndpoint = new ServiceEndpoint(theEmulatorHost, theEmulatorPort);

var publisherClient = await PublisherClient.CreateAsync(
    topicName,
    new PublisherClient.ClientCreationSettings(credentials: ChannelCredentials.Insecure, serviceEndpoint: serviceEndpoint));

要切换到真正的 PubSub,只需离开 ClientCreationSettings

【讨论】:

所以你必须来回更改代码才能使用模拟器?对我来说,这听起来像是灾难的收据。【参考方案3】:

您可以使用扩展方法.WithEmulatorDetection(EmulatorDetection.EmulatorOrProduction)ClientCreationSettings 上使用EmulatorDetection 属性。像这样:

PublisherClient publisher = await PublisherClient.CreateAsync(
        topicName, 
        new PublisherClient.ClientCreationSettings()
            .WithEmulatorDetection(EmulatorDetection.EmulatorOrProduction));

如果本地模拟器端点具有以下环境变量,这将起作用:PUBSUB_EMULATOR_HOST=localhost:8085

(如果您使用 Visual Studio,您可能需要重新启动 VS 才能检测到环境变量)

在 Windows 中,我在使用 set PUBSUB_EMULATOR_HOST=localhost:8085 命令时遇到了问题,所以我最终手动添加了它。

详情请看:https://cloud.google.com/pubsub/docs/emulator

额外提示:您可以使用 curl 将主题直接添加到 API:curl -X PUT http://localhost:8085/v1/projects/my-project-name/topics/my-topic

【讨论】:

以上是关于使用 GCloud 模拟器的 Google Cloud PubSub V1的主要内容,如果未能解决你的问题,请参考以下文章

使用 gcloud 连接到 Google Datastore

在 Google Compute Engine 上使用 gcloud 安装 node.js

使用 gcloud 客户端将日志写入 gcloud Vertex AI Endpoint 失败并显示 google.api_core.exceptions.MethodNotImplemented:

使用 gcloud-python 在 Google Cloud Storage 中设置元数据

在没有 gcloud 客户端的情况下访问 google 容器注册表

Google Compute Engine:无法从 gcloud 终端查询 API