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() } } }
func (this *Spout) InitSocket(pull, push string) (err error) { var reader, writer *zmq.Context reader, err = zmq.NewContext() if err != nil { return } this.Component.Reader, err = reader.NewSocket(zmq.PULL) if err != nil { return } err = this.Component.Reader.Connect("tcp://127.0.0.1:" + pull) if err != nil { return } writer, err = zmq.NewContext() if err != nil { return } this.Component.Writer, err = writer.NewSocket(zmq.PUSH) if err != nil { return } err = this.Component.Writer.Bind("tcp://127.0.0.1:" + push) return }
func NewSocketAndAddress(c *zmq.Context, bind bool, t zmq.Type, name string) (a *zmq.Socket, addr string, err error) { addr = fmt.Sprintf("inproc://_routerelement_internal-%d", getUniqueId()) if a, err = c.NewSocket(t); err != nil { goto Error } if name != "" { a.SetIdentity(name) } if bind { if err = a.Bind(addr); err != nil { goto Error } } else { if err = a.Connect(addr); err != nil { goto Error } } return Error: if a != nil { a.Close() a = nil } addr = "" return }
func NewPair(c *zmq.Context) (a *zmq.Socket, b *zmq.Socket, err error) { addr := fmt.Sprintf("inproc://_routerelement_internal-%d", getUniqueId()) if a, err = c.NewSocket(zmq.PAIR); err != nil { goto Error } if err = a.Bind(addr); err != nil { goto Error } if b, err = c.NewSocket(zmq.PAIR); err != nil { goto Error } if err = b.Connect(addr); err != nil { goto Error } return Error: if a != nil { a.Close() a = nil } if b != nil { b.Close() b = nil } return }
// 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 }
func TestMultipleContexts(t *testing.T) { chQuit := make(chan interface{}) chErr := make(chan error, 2) needQuit := false var sock1, sock2, serv1, serv2 *zmq.Socket var serv_ctx1, serv_ctx2, ctx1, ctx2 *zmq.Context var err error defer func() { if needQuit { chQuit <- true chQuit <- true <-chErr <-chErr } for _, s := range []*zmq.Socket{sock1, sock2, serv1, serv2} { if s != nil { s.SetLinger(0) s.Close() } } for _, c := range []*zmq.Context{serv_ctx1, serv_ctx2, ctx1, ctx2} { if c != nil { c.Term() } } }() addr1 := "tcp://127.0.0.1:9997" addr2 := "tcp://127.0.0.1:9998" serv_ctx1, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } serv1, err = serv_ctx1.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = serv1.Bind(addr1) if err != nil { t.Fatal("Bind:", err) } serv_ctx2, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } serv2, err = serv_ctx2.NewSocket(zmq.REP) if err != nil { t.Fatal("NewSocket:", err) } err = serv2.Bind(addr2) if err != nil { t.Fatal("Bind:", err) } new_service := func(sock *zmq.Socket, addr string) { socket_handler := func(state zmq.State) error { msg, err := sock.RecvMessage(0) if err != nil { return err } _, err = sock.SendMessage(addr, msg) return err } quit_handler := func(interface{}) error { return errors.New("quit") } reactor := zmq.NewReactor() reactor.AddSocket(sock, zmq.POLLIN, socket_handler) reactor.AddChannel(chQuit, 1, quit_handler) err = reactor.Run(100 * time.Millisecond) chErr <- err } go new_service(serv1, addr1) go new_service(serv2, addr2) needQuit = true time.Sleep(time.Second) // default context sock1, err = zmq.NewSocket(zmq.REQ) if err != nil { t.Fatal("NewSocket:", err) } sock2, err = zmq.NewSocket(zmq.REQ) if err != nil { t.Fatal("NewSocket:", err) } err = sock1.Connect(addr1) if err != nil { t.Fatal("sock1.Connect:", err) } err = sock2.Connect(addr2) if err != nil { t.Fatal("sock2.Connect:", err) } _, err = sock1.SendMessage(addr1) if err != nil { t.Fatal("sock1.SendMessage:", err) } _, err = sock2.SendMessage(addr2) if err != nil { t.Fatal("sock2.SendMessage:", err) } msg, err := sock1.RecvMessage(0) expected := []string{addr1, addr1} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock1.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } msg, err = sock2.RecvMessage(0) expected = []string{addr2, addr2} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock2.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } err = sock1.Close() sock1 = nil if err != nil { t.Fatal("sock1.Close:", err) } err = sock2.Close() sock2 = nil if err != nil { t.Fatal("sock2.Close:", err) } // non-default contexts ctx1, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } ctx2, err = zmq.NewContext() if err != nil { t.Fatal("NewContext:", err) } sock1, err = ctx1.NewSocket(zmq.REQ) if err != nil { t.Fatal("ctx1.NewSocket:", err) } sock2, err = ctx2.NewSocket(zmq.REQ) if err != nil { t.Fatal("ctx2.NewSocket:", err) } err = sock1.Connect(addr1) if err != nil { t.Fatal("sock1.Connect:", err) } err = sock2.Connect(addr2) if err != nil { t.Fatal("sock2.Connect:", err) } _, err = sock1.SendMessage(addr1) if err != nil { t.Fatal("sock1.SendMessage:", err) } _, err = sock2.SendMessage(addr2) if err != nil { t.Fatal("sock2.SendMessage:", err) } msg, err = sock1.RecvMessage(0) expected = []string{addr1, addr1} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock1.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } msg, err = sock2.RecvMessage(0) expected = []string{addr2, addr2} if err != nil || !arrayEqual(msg, expected) { t.Errorf("sock2.RecvMessage: expected %v %v, got %v %v", nil, expected, err, msg) } err = sock1.Close() sock1 = nil if err != nil { t.Fatal("sock1.Close:", err) } err = sock2.Close() sock2 = nil if err != nil { t.Fatal("sock2.Close:", err) } err = ctx1.Term() ctx1 = nil if err != nil { t.Fatal("ctx1.Term", nil) } err = ctx2.Term() ctx1 = nil if err != nil { t.Fatal("ctx2.Term", nil) } needQuit = false for i := 0; i < 2; i++ { // close(chQuit) doesn't work because the reactor removes closed channels, instead of acting on them chQuit <- true err = <-chErr if err.Error() != "quit" { t.Errorf("Expected error value quit, got %v", err) } } }