示例#1
0
文件: admin.go 项目: musicglue/skynet
func (sa *ServiceAdmin) Listen(addr *skynet.BindAddr, bindWait *sync.WaitGroup) {
	listener, err := addr.Listen()
	if err != nil {
		panic(err)
	}

	bindWait.Done()

	sa.service.Log.Trace(fmt.Sprintf("%+v", AdminListening{sa.service.Config}))

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			panic(err)
		}
		go sa.rpc.ServeCodec(bsonrpc.NewServerCodec(conn))
	}
}
示例#2
0
// this function is the goroutine that owns this service - all thread-sensitive data needs to
// be manipulated only through here.
func (s *Service) mux() {
loop:
	for {
		select {
		case conn := <-s.connectionChan:
			atomic.AddInt32(&s.Stats.Clients, 1)

			clientID := skynet.UUID()

			s.clientMutex.Lock()
			s.clientInfo[clientID] = ClientInfo{
				Address: conn.RemoteAddr(),
			}
			s.clientMutex.Unlock()

			// send the server handshake
			sh := skynet.ServiceHandshake{
				Registered: s.Registered,
				ClientID:   clientID,
			}
			encoder := bsonrpc.NewEncoder(conn)
			err := encoder.Encode(sh)
			if err != nil {
				s.Log.Error(err.Error())

				atomic.AddInt32(&s.Stats.Clients, -1)
				break
			}
			if !s.Registered {
				conn.Close()
				atomic.AddInt32(&s.Stats.Clients, -1)
				break
			}

			// read the client handshake
			var ch skynet.ClientHandshake
			decoder := bsonrpc.NewDecoder(conn)
			err = decoder.Decode(&ch)
			if err != nil {
				s.Log.Error("Error calling bsonrpc.NewDecoder: " + err.Error())
				atomic.AddInt32(&s.Stats.Clients, -1)
				break
			}

			// here do stuff with the client handshake

			go func() {
				s.RPCServ.ServeCodec(bsonrpc.NewServerCodec(conn))

				atomic.AddInt32(&s.Stats.Clients, -1)
			}()
		case register := <-s.registeredChan:
			if register {
				s.register()
			} else {
				s.unregister()
			}
		case _ = <-s.doneChan:
			go func() {
				for _ = range s.doneChan {
				}
			}()
			s.RemoveFromCluster()
			s.doozerChan <- doozerFinish{}
			break loop

		case _ = <-s.updateTicker.C:
			s.UpdateDoozerStats()
		}
	}
}