Example #1
3
func TestSocketEvent(t *testing.T) {

	var rep *zmq.Socket
	defer func() {
		if rep != nil {
			rep.SetLinger(0)
			rep.Close()
		}
	}()

	// REP socket
	rep, err := zmq.NewSocket(zmq.REP)
	if err != nil {
		t.Fatal("NewSocket:", err)
	}

	// REP socket monitor, all events
	err = rep.Monitor("inproc://monitor.rep", zmq.EVENT_ALL)
	if err != nil {
		t.Fatal("rep.Monitor:", err)
	}
	chMsg := make(chan string, 10)
	go rep_socket_monitor("inproc://monitor.rep", chMsg)
	time.Sleep(time.Second)

	// Generate an event
	err = rep.Bind("tcp://*:9689")
	if err != nil {
		t.Fatal("rep.Bind:", err)
	}

	rep.Close()
	rep = nil

	expect := []string{
		"EVENT_LISTENING tcp://0.0.0.0:9689",
		"EVENT_CLOSED tcp://0.0.0.0:9689",
		"Done",
	}
	i := 0
	for msg := range chMsg {
		if i < len(expect) {
			if msg != expect[i] {
				t.Errorf("Expected message %q, got %q", expect[i], msg)
			}
			i++
		} else {
			t.Error("Unexpected message: %q", msg)
		}
	}
	for ; i < len(expect); i++ {
		t.Errorf("Expected message %q, got nothing", expect[i])
	}
}
Example #2
0
//
// MonitorSocket creates a monitoring socket using given context and connects
// to a given socket to be monitored. Returns a channel to receive monitoring
// events. See event definitions here: http://api.zeromq.org/3-2:zmq-socket-monitor
//
func MonitorSocket(socket *zmq.Socket, name string) (<-chan zmq.Event, error) {
	endpoint := fmt.Sprintf("inproc://%v.%v.%v", name, os.Getpid(), time.Now().UnixNano())
	monCh := make(chan zmq.Event, 512) // make a buffered channel in case of heavy network activity
	go func() {
		monSock, err := zmq.NewSocket(zmq.PAIR)
		if err != nil {
			log.Println("Failed to start monitoring socket:", err.Error())
			return
		}
		monSock.Connect(endpoint)
		for {
			data, err := monSock.RecvMessageBytes(0)
			if err != nil {
				return
			}
			eventID := zmq.Event(binary.LittleEndian.Uint16(data[0][:2]))
			/*
				switch eventID {
				case zmq.EVENT_CONNECTED:
					log.Println("MonitorSocket: EVENT_CONNECTED", string(data[1]))
				case zmq.EVENT_CONNECT_DELAYED:
					log.Println("MonitorSocket: EVENT_CONNECT_DELAYED", string(data[1]))
				case zmq.EVENT_CONNECT_RETRIED:
					log.Println("MonitorSocket: EVENT_CONNECT_RETRIED", string(data[1]))
				case zmq.EVENT_LISTENING:
					log.Println("MonitorSocket: EVENT_LISTENING", string(data[1]))
				case zmq.EVENT_BIND_FAILED:
					log.Println("MonitorSocket: EVENT_BIND_FAILED", string(data[1]))
				case zmq.EVENT_ACCEPTED:
					log.Println("MonitorSocket: EVENT_ACCEPTED", string(data[1]))
				case zmq.EVENT_ACCEPT_FAILED:
					log.Println("MonitorSocket: EVENT_ACCEPT_FAILED", string(data[1]))
				case zmq.EVENT_CLOSED:
					log.Println("MonitorSocket: EVENT_CLOSED", string(data[1]))
				case zmq.EVENT_CLOSE_FAILED:
					log.Println("MonitorSocket: EVENT_CLOSE_FAILED", string(data[1]))
				case zmq.EVENT_DISCONNECTED:
					log.Println("MonitorSocket: EVENT_DISCONNECTED", string(data[1]))
				default:
					log.Printf("MonitorSocket: Unsupported event id: %#v - Message: %#v", eventID, data)
				}
			*/
			monCh <- zmq.Event(eventID)
		}
	}()
	return monCh, socket.Monitor(endpoint, MonitorEvents)
}
Example #3
0
// NewClientWithConnection returns a new Client to handle requests to the
// set of services at the other end of the connection.
// An existing connection in the form of a zmq socket together with the zmq
// context they were created with is used
func NewClientWithConnection(ctx *zmq.Context, conn *zmq.Socket) *Client {
	// A router socket is the middle-man between client requests and actually sending/receiving on the wire
	router, err := ctx.NewSocket(zmq.ROUTER)
	if err != nil {
		glog.Fatal(err)
	}
	if err := router.Bind(RouterURL); err != nil {
		glog.Fatal(err)
	}

	client := &Client{
		conn: conn,
		endpoints: endpoints{
			socket: conn,
		},
		router: router,
		ctx:    ctx,
	}

	// Start the proxy in an own routine since it is blocking
	go func() {
		if err := zmq.Proxy(conn, router, nil); err != nil {
			switch zmq.AsErrno(err) {
			case zmq.Errno(zmq.ETERM):
				glog.Info(err)
			case zmq.Errno(syscall.EINTR):
				glog.Info(err)
			default:
				glog.Info(zmq.AsErrno(err))
				glog.Info(err)
			}
			client.Close()
		}
	}()

	// Socket monitor for connect event
	monitorURL := "inproc://monitor"
	if err := conn.Monitor(monitorURL, zmq.EVENT_CONNECTED|zmq.EVENT_DISCONNECTED); err != nil {
		client.Close()
		glog.Fatal(err)
	}
	go client.monitor(monitorURL)

	return client
}