func (server *Server) monitor(ctx *zmq.Context, addr string) { sock, err := ctx.NewSocket(zmq.PAIR) if err != nil { glog.Fatal(err) } if err := sock.Connect(addr); err != nil { glog.Fatal(err) } defer sock.Close() var lock sync.Mutex var numClients int for { evtType, _, _, err := sock.RecvEvent(0) if err != nil { glog.Error(err) break } switch zmq.Event(evtType) { case zmq.EVENT_ACCEPTED: lock.Lock() numClients++ glog.Infof("Client #%d connected", numClients) lock.Unlock() case zmq.EVENT_DISCONNECTED: lock.Lock() glog.Infof("Client #%d disconnected", numClients) numClients-- lock.Unlock() } } }
// // 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) }