// Connect to addr and send/receive a message.
func client(addr net.Addr) {
	if c, err := electron.Dial(addr.Network(), addr.String()); check("dial", err) {
		defer c.Close(nil)
		if s, err := c.Sender(electron.Target("target")); check("sender", err) {
			fmt.Printf("client sending\n")
			s.SendSync(amqp.NewMessageWith("hello")) // Send and wait for server to Accept()
		if r, err := c.Receiver(electron.Source("source")); check("receiver", err) {
			if rm, err := r.Receive(); err == nil {
				fmt.Printf("client received %q\n", rm.Message.Body())
Example #2
func main() {
	flag.Usage = usage

	urls := flag.Args() // Non-flag arguments are URLs to receive from
	if len(urls) == 0 {
		log.Println("No URL provided")

	messages := make(chan amqp.Message) // Channel for messages from goroutines to main()
	defer close(messages)

	var wait sync.WaitGroup // Used by main() to wait for all goroutines to end.
	wait.Add(len(urls))     // Wait for one goroutine per URL.

	_, prog := path.Split(os.Args[0])
	container := electron.NewContainer(fmt.Sprintf("%v:%v", prog, os.Getpid()))
	connections := make(chan electron.Connection, len(urls)) // Connections to close on exit

	// Start a goroutine to for each URL to receive messages and send them to the messages channel.
	// main() receives and prints them.
	for _, urlStr := range urls {
		util.Debugf("Connecting to %s\n", urlStr)
		go func(urlStr string) { // Start the goroutine

			defer wait.Done()                 // Notify main() when this goroutine is done.
			url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.

			// Open a new connection
			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
			c, err := container.Connection(conn)
			connections <- c // Save connection so we can Close() when main() ends

			// Create a Receiver using the path of the URL as the source address
			r, err := c.Receiver(electron.Source(url.Path))

			// Loop receiving messages and sending them to the main() goroutine
			for {
				rm, err := r.Receive()
				switch err {
				case electron.Closed:
					util.Debugf("closed %s", urlStr)
				case nil:
					messages <- rm.Message

	// All goroutines are started, we are receiving messages.
	fmt.Printf("Listening on %d connections\n", len(urls))

	// print each message until the count is exceeded.
	for i := uint64(0); i < *count; i++ {
		m := <-messages
		util.Debugf("%s\n", util.FormatMessage(m))
	fmt.Printf("Received %d messages\n", *count)

	// Close all connections, this will interrupt goroutines blocked in Receiver.Receive()
	for i := 0; i < len(urls); i++ {
		c := <-connections
		util.Debugf("close %s", c)
	wait.Wait() // Wait for all goroutines to finish.