Micro如何接收web端的发布实现后台订阅?

2019-08-21 17:57:27 浏览数 (1)

不忘初心,砥砺前行

作者 | 陌无崖

转载请联系授权

导语

在web开发中有一种情况,我们或许希望在发送http请求的同时,后台服务订阅了该http请求,并对消息作出相应的处理,该怎么做呢?我们之前学过broker模式,这种模式可以在两个后台服务进行消息的发布和订阅,其实我们仍然可以利用这一点。

客户端

定义一个主题发布消息

我们定义了一个字符串,用topic变量进行接收。

代码语言:javascript复制
var (
    topic = "go.micro.web.topic.hi"
)
发布消息

使用broker.Message存储我们消息,同时使用broker.Publish()发布我们的消息,等待订阅者接收消息。这里需要注意的一个函数time.Now().String()代表获取当前时间并转换成字符串。

代码语言:javascript复制
func pub(name string) {
    msg := &broker.Message{
        Header: map[string]string{
            "name": fmt.Sprintf("%s", name),
        },
        Body: []byte(fmt.Sprintf("%s:%s", name, time.Now().String())),
    }
    if err := broker.Publish(topic, msg); err != nil {
        log.Logf("[pub] 发布消息:%s", err)
    } else {
        log.Logf("[pub] 发布消息: %s", string(msg.Body))
    }
}
定义Handler

因为我们将要使用web端作为客户端发送请求,因此需要一个handler接收我们的请求,并做出响应。首先我们添加头信息,解析我们的参数,并把它存储在response变量中,该变量的类型为map[string]interface{},函数体中的time.Now().UnixNano()代表获取当前时间戳,单位为纳秒。另外还需要注意的是json.NewEncoder(w)将会创建一个将数据写入w的*Encoder。在之前我们经常将数据转换成[]byte类型,并使用w.write(body)进行写入w,这种比较麻烦,现在可以使用这种方式就可以将json数据写入w中,而Encode函数将会对参数进行json编码并同时写入我们之前创建的*Encoder,

代码语言:javascript复制
// 定义一个handler
func hi(w http.ResponseWriter, r *http.Request) {
    w.Header().Add("Content-Type", "application/json;charset=utf-8")
    _ = r.ParseForm()
    // 返回结果
    response := map[string]interface{}{
        "ref":  time.Now().UnixNano(),
        "data": "Hello!"   r.Form.Get("name"),
    }
    //返回json结构
    // NewEncoder创建一个将数据写入w的*Encoder。
    // Encode将v的json编码写入输出流,并会写入一个换行符,
    if err := json.NewEncoder(w).Encode(response); err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    pub(r.Form.Get("name"))
}
创建发布服务

函数体中告诉我们该服务将会监听8088的端口

代码语言:javascript复制
// 创建一个服务
    service := web.NewService(
        web.Name("go.micro.book.web.pub"),
        web.Version("latest"),
        web.Address(":8088"),
    )
    // 初始化我们的服务
    _ = service.Init()
    service.HandleFunc("/hi", hi)
    // 运行服务
    if err := service.Run(); err != nil {
        log.Fatal(err)
    }

订阅

订阅主题

同样我们也需要声明我们将要订阅什么主题,与客户端保持一致即可

代码语言:javascript复制
var (
    topic = "go.micro.web.topic.hi"
)
订阅消息

首先需要实例化一个broker,并为broker设置一个监听地址,然后我们使用Subscribe函数实现我们的订阅

代码语言:javascript复制
bk := broker.NewBroker(
        broker.Addrs(fmt.Sprintf("%s:%d", "192.168.10.150", 11089)),
    )
    _, err := bk.Subscribe(topic, func(p broker.Event) error {
        log.Logf("[sub]:Received Body: %s,Header:%s", string(p.Message().Body), p.Message().Header)
        return nil
    })

因为这仍然是一个服务,我们同样需要进行创建服务

代码语言:javascript复制
s := micro.NewService(
        micro.Name("go.micro.book.web.sub"),
        micro.Version("latest"),
        micro.Address(":8099"),
        micro.Broker(bk),
    )
    s.Init()
    _ = s.Run()

测试

启动
发送http请求
控制台打印

非常感谢你保持着耐心读完这篇文章,我是陌无崖,一个专注于Golang后端开发的互联网从业人员,熟悉RabbitMQ,Docker,微服务等,获取更多知识分享,文章末尾扫码关注,每日推送,准时获取更多分享。

本文代码参考:

micro教程系列:https://github.com/micro-in-cn/tutorials/blob/

END

今日推荐阅读

RabbitMQ系列笔记广播模式和路由模式 RabbitMQ系列笔记入门篇

RabbitMQ系列笔记work模式

RabbitMQ系列笔记work模式

protoc语法详解及结合grpc定义服务

Golang中Model的使用

基于Nginx和Consul构建高可用及自动发现的Docker服务架构

▼关注我,一起成长

主要分享 学习心得、笔记、随笔▼

0 人点赞