duanjianlu0506 2014-10-11 11:19
浏览 194
已采纳

一个连接能否在go API中为Rabbitmq支持多个通道?

package main

import (
"fmt"
"github.com/streadway/amqp"
"time"
)

// Every connection should declare the topology they expect
func setup(url, queue string) (*amqp.Connection, *amqp.Channel, error) {
    //setup connection
    conn, err := amqp.Dial(url)
    if err != nil {
        return nil, nil, err
    }
    //build channel in the connection
    ch, err := conn.Channel()
        if err != nil {
        return nil, nil, err
    }
    //queue declare
    if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
        return nil, nil, err
    }

    return conn, ch, nil
}

func main() {
    //amqp url
    url := "amqp://guest:guest@127.0.0.1:5672";
    for i := 1; i <= 2; i++ {
        fmt.Println("connect ", i)
        //two goroutine   
        go func() {
            //queue name
            queue := fmt.Sprintf("example.reconnect.%d", i)
            //setup channel in the tcp connection
            _, pub, err := setup(url, queue)
            if err != nil {
                fmt.Println("err publisher setup:", err)
                return
            }
            // Purge the queue from the publisher side to establish initial state
            if _, err := pub.QueuePurge(queue, false); err != nil {
                fmt.Println("err purge:", err)
                return
            }
            //publish msg
            if err := pub.Publish("", queue, false, false, amqp.Publishing{
                Body: []byte(fmt.Sprintf("%d", i)),
            }); err != nil {
                fmt.Println("err publish:", err)
                return
            }
            //keep running
            for{
                time.Sleep(time.Second * 20)
            }
        }()
    }
    //keep running
    for {
        time.Sleep(time.Second * 20)
    }
}

I thought there is only one connection between the program and mq-server,

but there are two connection,one connection can only support one channel,why?

can't the two goroutine share the same tcp connection?

Socket descriptor can share in all threads of a process in the theory.

Why the two goroutine don't share one socket but have their own channel?

The model by hand:

model1

The real model in rabbitmq: model2

  • 写回答

1条回答 默认 最新

  • douluxia0606 2014-10-11 12:52
    关注

    Looking at the source for the library it appears as though you can call conn.Channel() as many times as you like and it creates a new stream of communication over the same connection.

    Ok, I tried it, here's a working example... One goroutine, one connection, two channels I setup the receiver, then send a message, then read from the receiver channel

    if you wanted multiple queue's bound in one goroutine, you would call rec.Consume twice and then select across the queues.

    package main
    
    import (
        "fmt"
        "github.com/streadway/amqp"
        "os"
    )
    
    func main() {
        conn, err := amqp.Dial("amqp://localhost")
        e(err)
        defer conn.Close()
        fmt.Println("Connected")
        rec, err := conn.Channel()
        e(err)
    
        fmt.Println("Setup receiver")
        rq, err := rec.QueueDeclare("go-test", false, false, false, false, nil)
        e(err)
        msgs, err := rec.Consume(rq.Name, "", true, false, false, false, nil)
        e(err)
    
        fmt.Println("Setup sender")
        send, err := conn.Channel()
        e(err)
        sq, err := send.QueueDeclare("go-test", false, false, false, false, nil)
        e(err)
    
        fmt.Println("Send message")
        err = send.Publish("", sq.Name, false, false, amqp.Publishing{
            ContentType: "text/plain",
            Body:        []byte("This is a test"),
        })
        e(err)
    
        msg := <-msgs
        fmt.Println("Received from:", rq, "msg:", string(msg.Body))
    }
    
    func e(err error) {
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    }
    

    Output on my box:

    $ go run rmq.go 
    Connected
    Setup receiver
    Setup sender
    Send message
    Received from: {go-test 0 0} msg: This is a test
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 求解达问题(有红包)
  • ¥15 请解包一个pak文件
  • ¥15 不同系统编译兼容问题
  • ¥100 三相直流充电模块对数字电源芯片在物理上它必须具备哪些功能和性能?
  • ¥30 数字电源对DSP芯片的具体要求
  • ¥20 antv g6 折线边如何变为钝角
  • ¥30 如何在Matlab或Python中 设置饼图的高度
  • ¥15 nginx中的CORS策略应该如何配置
  • ¥30 信号与系统实验:采样定理分析
  • ¥100 我想找人帮我写Python 的股票分析代码,有意请加mathtao