// NewPeer creates and returns a new Peer for communicating with AMQP brokers. func NewPeer(host string) (*Peer, error) { conn, err := amqp.Dial("amqp://" + host) if err != nil { return nil, err } channel, err := conn.Channel() if err != nil { return nil, err } queue, err := channel.QueueDeclare( broker.GenerateName(), // name false, // not durable false, // delete when unused true, // exclusive false, // no wait nil, // arguments ) if err != nil { return nil, err } err = channel.ExchangeDeclare( exchange, // name "fanout", // type false, // not durable false, // auto-deleted false, // internal false, // no wait nil, // arguments ) if err != nil { return nil, err } return &Peer{ conn: conn, queue: queue, channel: channel, send: make(chan []byte), errors: make(chan error, 1), done: make(chan bool), }, nil }
// Subscribe prepares the peer to consume messages. func (n *Peer) Subscribe() error { consumer, err := nsq.NewConsumer(topic, broker.GenerateName(), nsq.NewConfig()) if err != nil { return err } consumer.AddHandler(nsq.HandlerFunc(func(message *nsq.Message) error { n.messages <- message.Body return nil })) if err := consumer.ConnectToNSQD(n.host); err != nil { return err } n.consumer = consumer return nil }
func NewPeer(host string) (*Peer, error) { p := &Peer{} p.client = amps.NewClient("client") p.client.MessageHandler = p p.client.ErrorHandler = p err := p.client.Connect("localhost:5000") for err != nil { err = p.client.Connect("localhost:5000") } if err == nil { p.wrchan = make(chan []byte, 4096) p.readchan = make(chan []byte, 4096) p.errchan = make(chan error) p.wrmsg.Command = "p" p.wrmsg.Topic = "queue" } else { fmt.Printf("PEER ERROR %s\n", err) } go func() { for { data := <-p.wrchan p.wrmsg.Data = string(data) err := p.client.Send(&p.wrmsg) if err != nil { break } } }() // logon logonMessage := amps.Message{ Command: "logon", AckType: "processed", UserId: broker.GenerateName(), } p.client.Send(&logonMessage) <-p.readchan return p, nil }
// Subscribe prepares the peer to consume messages. func (c *Peer) Subscribe() error { // Subscription names must start with a lowercase letter, end with a // lowercase letter or number, and contain only lowercase letters, numbers, // dashes, underscores or periods. c.subscription = strings.ToLower(fmt.Sprintf("x%sx", broker.GenerateName())) exists, err := pubsub.SubExists(c.context, c.subscription) if err != nil { return err } if exists { return fmt.Errorf("Subscription %s already exists", c.subscription) } if err := pubsub.CreateSub(c.context, c.subscription, topic, 0, ""); err != nil { return err } go c.ack() go func() { // TODO: Can we avoid using atomic flag? for atomic.LoadInt32(&c.stopped) != stopped { messages, err := pubsub.PullWait(c.context, c.subscription, bufferSize) if err != nil { // Timed out. continue } ids := make([]string, len(messages)) for i, message := range messages { ids[i] = message.AckID c.messages <- message.Data } c.acks <- ids } }() return nil }