Go语言通过ZMQ实现消息传递

本文是关于株式会社Ice Style Advent Calendar的第23篇文章。

这次我们将使用去年在PHP Advent Calendar中提到的PHP消息发送和接收(zeromq)来简单地在Golang中使用。

zmq利用准备的机制

如果要在golang中使用zmq,可以使用zeromq/goczmq库。

如果您使用Mac,建议您使用Homebrew等工具。

$ brew install zeromq
$ brew install czmq

在这里,我们假设消息的发送方是PHP。对于PHP,需要使用libzmq和php-zmq扩展。

libzmq 的中文释义是什么?

$ git clone git://github.com/zeromq/libzmq.git
$ cd libzmq/
$ ./autogen.sh
$ ./configure && make
$ make install

PHP-ZMQ 是一个用于 PHP 编程语言的消息队列库。

$ git clone git://github.com/mkoppanen/php-zmq.git
$ cd php-zmq/
$ phpize
$ ./configure && make
$ make install

可以使用remi仓库或其他方式。
我们将使用DEALER和ROUTER套接字进行操作。

用PHP发送消息

使用php-zmq扩展发送消息。
在此示例中,连接到5555,并将套接字类型设置为\ZMQ::SOCKET_DEALER。

<?php

$socket = new \ZMQSocket(new \ZMQContext(), \ZMQ::SOCKET_DEALER);
$socket->connect("tcp://localhost:5555");
$receive = $socket->send("this is PHP")->recv();

echo "from golang: $receive\n";

在客户端发送消息后,PHP会一直等待来自golang的消息返回。

golang收到消息

使用包中提供的示例代码,接收客户端消息后进行返回。

package main

import (
    "log"
    "github.com/zeromq/goczmq"
)

func main() {

    router, err := goczmq.NewRouter("tcp://*:5555")
    if err != nil {
        log.Fatal(err)
    }
    defer router.Destroy()

    request, err := router.RecvMessage()
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("router received '%s' from '%v'", request[1], request[0])

    err = router.SendFrame(request[0], goczmq.FlagMore)
    if err != nil {
        log.Fatal(err)
    }

    err = router.SendFrame([]byte("this is golang"), goczmq.FlagNone)
    if err != nil {
        log.Fatal(err)
    }
}

如果要实际运行此项,请按以下方式操作。

# クライアントからメッセージを送信
$ php client.php
# 受信待機
$ ./main

你可以使用这个来指示创建索引,例如使用类似Bleve的简单搜索包。

Bleve的例子

布雷维(Bleve)是一个客户端,在消息传递中仅指示进行索引添加操作,而不接收任何接收。

import (
    "log"
    "github.com/zeromq/goczmq"
    "github.com/blevesearch/bleve"
)


type Document struct {
    Content  string
}

func main() {

    router, err := goczmq.NewRouter("tcp://*:5555")
    if err != nil {
        log.Fatal(err)
    }
    defer router.Destroy()

    request, err := router.RecvMessage()
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("router received '%s' from '%v'", request[1], request[0])

    mapping := bleve.NewIndexMapping()
    index, err := bleve.New("search.bleve", mapping)
    if err != nil {
        panic(err)
        return
    }
    // index登録
    index.Index("1", Document{string(request[1])})
}

让我们尝试引入zmq等工具,以便通过消息传递来开发简单的应用程序。这样做可以使开发变得更加容易!

广告
将在 10 秒后关闭
bannerAds