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的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依 ...
随机推荐
- 使用gettid() 注意事项
gettid()这个函数不可以在程序中直接使用,它是Linux本身的一个函数, 但是:仅包含#include <sys/types.h>,然后使用,编译时会报该函数未定义之类的错误! 解决 ...
- 084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字
084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字 本文知识点:构造方法-this关键字 说明:因为时间紧 ...
- 036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构
036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构 本文知识点:Java中的嵌套if结构 什么是嵌套if结构? 概念: 嵌套if结构 ...
- 为什么很多国内公司在做 AI 芯片?
据网上搜到的新闻报道,截止2019年,已经有20家企业投入到 AI 芯片的研发中,其中有很多厂商的芯片已经流片甚至商用了.为何有这么多公司在做AI芯片呢?简单来讲就是四个字:有利可图.具体来说有以下三 ...
- mongoose 查询数据属性为数组,且包含某个值的方法
mongoose在创建schema的时候有些属性需要设置为数组类型,比如商品图片.商品标签.不同尺寸.价格等. 那么怎么查询具有某个标签的商品了,下面记录一下两种情况: 查询具有'vue'标签的文章 ...
- 开始接触flex
flex框架使用的是.mxml后缀的文件,可以在Eclipse导入flex开发的插件.代码写完之后需要进行编译成为.swf文件成功之后才可以正常运行.现在刚开始接触金融的项目,需求什么的还有很多不是理 ...
- Python+Appium自动化测试(13)-toast定位
一,前言 在app自动化测试的过程中经常会遇到需要对toast进行定位,最常见的就是定位toast或者获取toast的文案进行断言,如下图,通过定位"登录成功"的toast就可以断 ...
- 多测师_python基本介绍001
python 一.python的介绍 python 是一门面向对象,解释型,动态类型语言 面向对象:在python中 一切皆为对象 解释型语言:边解释,边执行, 动态类型:就是检查是在运行才做的. 动 ...
- MeteoInfoLab脚本示例:风场矢量图
读取风场U/V变量数据,可以从U/V计算出风速:speed = sqrt(u*u+v*v).quiverm函数用来绘制风场矢量图,参数中包括U/V变量,如果要绘制彩色风场还需要第三个变量,这里是风速s ...
- set的运用 例题5-3 安迪的第一个字典(Andy's First Dictionary,Uva 10815)
#include<bits/stdc++.h>using namespace std;set<string> dict;int main(){ string s, buf; w ...