Dapr Golang HTTP 调用
Dapr Golang HTTP 调用
版本介绍
- Go 版本:1.15
- Dapr Go SKD 版本:0.11.1
工程结构

从上图可知,新建 3 个 Go 启动项目,cmd 为启动项目目录,其中 client/a/main.go 为客户端,用于调用服务。service/http/b、service/http/c 为服务项目。调用路径如下图所示。
go-client-a--1-->go-service-b;
go-service-b--2-->go-service-c;
go-service-c--3-->go-service-b;
go-service-b--4-->go-client-a;
- go-client-a 作为客户端调用服务 go-service-b;
- go-service-b 作为服务中转,既收来自 go-client-a 客户端的请求,又发起对 go-service-c 的调用;
- go-service-c 响应 go-service-b 的请求;
- go-service-b 响应 go-client-a 的请求。
internal
response.go 文件,封装返回数据。数据结构如下:
package internal
import (
"encoding/json"
"log"
)
type HttpResult struct {
Message string
}
func (r *HttpResult) ToBytes() (bytes []byte) {
var err error
bytes, err = json.Marshal(r)
if err != nil {
log.Fatal("数据转换失败")
}
return
}
go-service-c
go-service-c 做为调用链路末端,只需要提供监听端口,以及绑定路由。下面方法通过 s.AddServiceInvocationHandler("/hello", helloHandler) 方法绑定路由和处理方法。以下为 go-service-c 源码。
package main
import (
"context"
"errors"
"github.com/Zhang-Byte/dapr-golang/internal"
"github.com/dapr/go-sdk/service/common"
daprd "github.com/dapr/go-sdk/service/http"
"log"
"net/http"
)
func main() {
s := daprd.NewService(":9003")
if err := s.AddServiceInvocationHandler("/hello", helloHandler); err != nil {
log.Fatalf("error adding invocation handler: %v", err)
}
if err := s.Start(); err != nil && err != http.ErrServerClosed {
log.Fatalf("error listenning: %v", err)
}
}
func helloHandler(_ context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
if in == nil {
err = errors.New("invocation parameter required")
return
}
log.Printf("The go-service-c service method hello has been invoked,recieve message is %v", string(in.Data))
httpResult := internal.HttpResult{Message: "This message is from Service C."}
out = &common.Content{
Data: httpResult.ToBytes(),
ContentType: in.ContentType,
DataTypeURL: in.DataTypeURL,
}
return
}
启动命令:
dapr run --app-id go-service-c \
--app-protocol http \
--app-port 9003 \
--dapr-http-port 3501 \
--log-level debug \
--components-path ./config \
go run ./cmd/service/http/c/main.go
go-service-b
go-service-b 相较于 go-service-c 的代码来说,添加了初始化客户端并发送请求的内容。查看代码 invokeService() 每次都会调用 client(),在 client() 中方法看上去每次都会新建一个客户端,查看 dapr 源码注释可知(Note, this default factory function creates Dapr client only once. All subsequent invocations will return the already created instance. ) 每次只会返回已经创建好的实例,因此使用完以后不必关闭此客户端。
package main
import (
"context"
"encoding/json"
"errors"
"github.com/Zhang-Byte/dapr-golang/internal"
dapr "github.com/dapr/go-sdk/client"
"github.com/dapr/go-sdk/service/common"
"log"
"net/http"
)
import daprd "github.com/dapr/go-sdk/service/http"
func main() {
s := daprd.NewService(":9002")
if err := s.AddServiceInvocationHandler("/hello", helloHandler); err != nil {
log.Fatalf("error adding invocation handler: %v", err)
}
if err := s.Start(); err != nil && err != http.ErrServerClosed {
log.Fatalf("error listenning: %v", err)
}
}
func helloHandler(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
if in == nil {
err = errors.New("invocation parameter required")
return
}
log.Printf("The go-service-b service method hello has been invoked,recieve message is %v", string(in.Data))
msg := invokeService(ctx)
httpResult := internal.HttpResult{Message: msg}
out = &common.Content{
Data: httpResult.ToBytes(),
ContentType: in.ContentType,
DataTypeURL: in.DataTypeURL,
}
return
}
func invokeService(ctx context.Context) (msg string) {
client := client()
content := &dapr.DataContent{
ContentType: "text/plain",
Data: []byte("This is golang Service B."),
}
resp, err := client.InvokeServiceWithContent(ctx, "go-service-c", "hello", content)
if err != nil {
panic(err)
}
var result internal.HttpResult
if err := json.Unmarshal(resp, &result); err != nil {
log.Printf(err.Error())
}
msg = result.Message
return
}
func client() dapr.Client {
client, err := dapr.NewClient()
if err != nil {
panic(err)
}
return client
}
启动命令:
dapr run --app-id go-service-b \
--app-protocol http \
--app-port 9002 \
--dapr-http-port 3500 \
--log-level debug \
--components-path ./config \
go run ./cmd/service/http/b/main.go
go-client-a
最后创建客户端,客户端每间隔 5 秒发起一次请求到 go-service-b 。
package main
import (
"context"
dapr "github.com/dapr/go-sdk/client"
"log"
"time"
)
func main() {
ctx := context.Background()
// create the client
client, err := dapr.NewClient()
if err != nil {
panic(err)
}
defer client.Close()
content := &dapr.DataContent{
ContentType: "text/plain",
Data: []byte("This is client A."),
}
for {
resp, err := client.InvokeServiceWithContent(ctx, "go-service-b", "hello", content)
if err != nil {
panic(err)
}
log.Printf("go-service-b method hello has invoked, response: %s", string(resp))
time.Sleep(time.Second * 5)
}
}
启动命令:
dapr run --app-id go-client-a \
--components-path ./config \
--log-level debug \
go run ./cmd/client/a/main.go
总结
client 启动后,得到返回值
== APP == 2020/11/06 11:26:41 go-service-b method hello has invoked, response: {"Message":"This message is from Service C."}
go-service-b 打印内容为:
== APP == 2020/11/06 11:31:51 The go-service-b service has been invoked,recieve message is This is client A.
go-service-c 打印内容为:
== APP == 2020/11/06 11:33:31 The go-service-c service method hello has been invoked,recieve message is This is golang Service B.
在命令行界面中输入 dapr dashboard 得到输出 Dapr Dashboard running on http://localhost:8080,访问 http://localhost:8080

源码地址:https://github.com/ZhangX-Byte/dapr-golang
Dapr Golang HTTP 调用的更多相关文章
- Dapr Java Http 调用
版本介绍 Java 版本:8 Dapr Java SKD 版本:0.9.2 Dapr Java-SDK HTTP 调用文档 有个先决条件,内容如下: Dapr and Dapr CLI. Java J ...
- Dapr DotNet5 HTTP 调用
Dapr DotNet5 HTTP 调用 版本介绍 Dotnet 版本:5.0.100 Dapr dotnet 版本:0.12.0-preview01 注意: Asp.Net Core 项目中的 la ...
- 手把手教你学Dapr - 4. 服务调用
上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...
- [Golang] cgo 调用 .so 捕获异常问题
最近需要在 go 中去调用 .so 库去完成一些事情,go 方面,利用 cgo 可以顺利的调用 .so 中的方法,但是有个问题是 go 没法捕获 .so 那边出现的异常.如果 .so 那边异常了,那么 ...
- golang动态调用方法
package main import ( "fmt" "reflect" ) type YourT1 struct { } func (y *YourT1) ...
- C/C++调用Golang 二
C/C++调用Golang 二 <C/C++调用Golang 一>简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用.本文总结具体项目中的使用场景,将介绍三种较复杂的 ...
- golang 查看代码调用关系图
go-callvis 是github上一个开源项目,可以用来查看golang代码调用关系. 安装 安装graphviz $ brew install graphviz 安装go-callvis go ...
- Dapr 运用之集成 Asp.Net Core Grpc 调用篇
前置条件: <Dapr 运用> 改造 ProductService 以提供 gRPC 服务 从 NuGet 或程序包管理控制台安装 gRPC 服务必须的包 Grpc.AspNetCore ...
- Golang调用Dll案例
Golang调用Dll案例 前言 在家办公已经两个多星期了,目前最大的困难就是网络很差.独自一个人用golang开发调用dll的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依 ...
随机推荐
- 什么是64位和32位internet explorer
什么是64位和32位internet explorer 如果您使用 64 位版本的 Internet Explorer 时,您会遇到问题,请尝试使用 32 位版本的 Internet Explorer ...
- python单元测试框架pytest
首先祝大家国庆节日快乐,这个假期因为我老婆要考注会,我也跟着天天去图书馆学了几天,学习的感觉还是非常不错的,这是一篇总结. 这篇博客准备讲解一下pytest测试框架,这个框架是当前最流行的python ...
- 生成器generator和迭代器Iterator
一.列表生成式 在学习生成器迭代器之前先了解一下什么是列表生成式,列表生成式是Python内置的非常简单却强大的可以用来创建list的生成式.什么意思?举个例子,如果想生成列表[0,1,2 ...
- P2832 行路难
题面 Link 题目背景 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述 山区有 \(n\) 座山.山之间有 \(m\) 条羊肠小道,每条连接两座山,只能单向通过, ...
- BSGS算法解析
前置芝士: 1.快速幂(用于求一个数的幂次方) 2.STL里的map(快速查找) 详解 BSGS 算法适用于解决高次同余方程 \(a^x\equiv b (mod p)\) 由费马小定理可得 x &l ...
- JavaCV FFmpeg采集摄像头YUV数据
前阵子使用利用树莓派搭建了一个视频监控平台(传送门),不过使用的是JavaCV封装好的OpenCVFrameGrabber和FFmpegFrameRecorder. 其实在javacpp项目集中有提供 ...
- Java虚拟机诊断利器
Java虚拟机诊断利器
- 多测师讲解python函数 _zip_高级讲师肖sir
# zip函数 #zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存.1.使用zip讲两个列表打印出来的结果是 ...
- 彻底根治window弹窗小广告(今日热点)
在一个阴雨蒙蒙的下午,我上完厕所回到工位,输入锁屏密码,解锁,蹦出来三个小广告,我......这还能忍??? 废话不多说,开搞! 一.广告分为两种: 红色字的今日热点 蓝色字的今日热点 二.追溯根源: ...
- xuexi0.2
1.数据结构就是研究数据如何排布和如何加工. 2.数组的目的是为了管理程序中类型相同,意义相关的变量. 3.数组的优势是比较简单,可以通过访问下标来进行随机访问.数组的限制:元素类型必须相同,数组的大 ...