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 为服务项目。调用路径如下图所示。

graph LR;
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;
  1. go-client-a 作为客户端调用服务 go-service-b;
  2. go-service-b 作为服务中转,既收来自 go-client-a 客户端的请求,又发起对 go-service-c 的调用;
  3. go-service-c 响应 go-service-b 的请求;
  4. 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 调用的更多相关文章

  1. Dapr Java Http 调用

    版本介绍 Java 版本:8 Dapr Java SKD 版本:0.9.2 Dapr Java-SDK HTTP 调用文档 有个先决条件,内容如下: Dapr and Dapr CLI. Java J ...

  2. Dapr DotNet5 HTTP 调用

    Dapr DotNet5 HTTP 调用 版本介绍 Dotnet 版本:5.0.100 Dapr dotnet 版本:0.12.0-preview01 注意: Asp.Net Core 项目中的 la ...

  3. 手把手教你学Dapr - 4. 服务调用

    上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...

  4. [Golang] cgo 调用 .so 捕获异常问题

    最近需要在 go 中去调用 .so 库去完成一些事情,go 方面,利用 cgo 可以顺利的调用 .so 中的方法,但是有个问题是 go 没法捕获 .so 那边出现的异常.如果 .so 那边异常了,那么 ...

  5. golang动态调用方法

    package main import ( "fmt" "reflect" ) type YourT1 struct { } func (y *YourT1) ...

  6. C/C++调用Golang 二

    C/C++调用Golang 二 <C/C++调用Golang 一>简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用.本文总结具体项目中的使用场景,将介绍三种较复杂的 ...

  7. golang 查看代码调用关系图

    go-callvis 是github上一个开源项目,可以用来查看golang代码调用关系. 安装 安装graphviz $ brew install graphviz 安装go-callvis go ...

  8. Dapr 运用之集成 Asp.Net Core Grpc 调用篇

    前置条件: <Dapr 运用> 改造 ProductService 以提供 gRPC 服务 从 NuGet 或程序包管理控制台安装 gRPC 服务必须的包 Grpc.AspNetCore ...

  9. Golang调用Dll案例

    Golang调用Dll案例 前言 在家办公已经两个多星期了,目前最大的困难就是网络很差.独自一个人用golang开发调用dll的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依 ...

随机推荐

  1. GUI应用编程初体验

    不同平台的GUI实现原理是一样的. 本实验基于 windos平台. 先捋一捋概念 什么是消息队列(Message Queue)假 设一个场景:系统正在处理WM_PAINT消息,就在这时用户在键盘上敲击 ...

  2. 07 Sublime Text3常用快捷键

    通用常用类(General) ↑↓←→:上下左右移动光标,注意不是不是 KJHL ! Alt:调出菜单 Ctrl + Shift + P:调出命令板(Command Palette) Ctrl + ` ...

  3. matlab中get查询图形对象属性

    来源:https://ww2.mathworks.cn/help/matlab/ref/get.html?searchHighlight=get&s_tid=doc_srchtitle get ...

  4. 怀疑安装MySQL之后,导致OrCAD Capture、Allegro就打不开

    记得在异常出现之前,只安装了MySQL,之后OrCAD Capture.Allegro就打不开了. Capture.exe - 系统错误 allegro.exe - 系统错误 我尝试在Cadence的 ...

  5. Camera插件之CinematicCamera介绍

    Camera插件之CinematicCamera 继承自PerspectiveCame 构造函数引用的PerspectiveCamera的构造函数, 代码如下 var CinematicCamera ...

  6. JAVA基础 随机点名器案例

    1.1      案例介绍 随机点名器,即在全班同学中随机的找出一名同学,打印这名同学的个人信息. 此案例在我们昨天课程学习中,已经介绍,现在我们要做的是对原有的案例进行升级,使用新的技术来实现. 我 ...

  7. 多测师讲解pythonl _字符,列表,元组,字典,集合,归纳_高级讲师肖sir

  8. 多测师讲解pyhon__hashlib_高级讲师肖sir

    一.加密,加密成16进制的字符串 # import hashlib # 导入hashlib模块# md = hashlib.md5() # 获取一个md5加密算法对象# md.update('需要加密 ...

  9. 阿里百秀后台管理项目笔记 ---- Day01

    摘要 在此记录一下阿里百秀项目的教学视频的学习笔记,部分页面被我修改了,某些页面效果会不一样,基本操作是一致的,好记性不如烂笔头,加油叭!!! step 1 : 整合全部静态页面 将静态页面全部拷贝到 ...

  10. 快速掌握Java8 Stream函数式编程技巧

    函数式编程优势 "函数第一位",即函数可以出现在任何地方. 可以把函数作为参数传递给另一个函数,还可以将函数作为返回值. 让代码的逻辑更清晰更优雅. 减少了可变量(Immutabl ...