예제 #1
0
func TestSend(t *testing.T) {
	client, server := net.Pipe()
	go doServiceHandshake(server, true, t)

	cn, err := NewConnectionFromNetConn("TestRPCService", client)
	c := cn.(*Conn)

	s := rpc.NewServer()
	var ts TestRPCService
	s.Register(&ts)
	go s.ServeCodec(bsonrpc.NewServerCodec(server))

	var tp TestParam
	tp.Val1 = "Hello World"
	tp.Val2 = 10

	ri := &skynet.RequestInfo{}

	ts.TestMethod = func(in skynet.ServiceRPCIn, out *skynet.ServiceRPCOut) (err error) {
		out.Out, err = bson.Marshal(&tp)

		var t TestParam

		if err != nil {
			return
		}

		if in.ClientID != c.clientID {
			return errors.New("Failed to set ClientID on request")
		}

		if in.Method != "Foo" {
			return errors.New("Failed to set Method on request")
		}

		if *in.RequestInfo != *ri {
			return errors.New("Failed to set RequestInfo on request")
		}

		err = bson.Unmarshal(in.In, &t)
		if err != nil {
			return
		}

		if t.Val1 != tp.Val1 || tp.Val2 != tp.Val2 {
			return errors.New("Request failed to send proper data")
		}

		return
	}

	err = c.Send(ri, "Foo", tp, &tp)
	if err != nil {
		t.Error(err)
		return
	}

	c.Close()
	server.Close()
}
예제 #2
0
파일: admin.go 프로젝트: smarinskaya/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))
	}
}
예제 #3
0
파일: service.go 프로젝트: bubble66/skynet
// 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:
			go func() {
				clientID := config.NewUUID()

				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,
					Name:       s.Name,
				}

				codec := bsonrpc.NewServerCodec(conn)

				log.Println(log.TRACE, "Sending ServiceHandshake")
				err := codec.Encoder.Encode(sh)
				if err != nil {
					log.Println(log.ERROR, "Failed to encode server handshake", err.Error())
					conn.Close()
					return
				}
				if !s.Registered {
					log.Println(log.ERROR, "Connection attempted while unregistered. Closing connection")
					conn.Close()
					return
				}

				// read the client handshake
				var ch skynet.ClientHandshake
				log.Println(log.TRACE, "Reading ClientHandshake")
				err = codec.Decoder.Decode(&ch)
				if err != nil {
					log.Println(log.ERROR, "Error decoding ClientHandshake: "+err.Error())
					conn.Close()
					return
				}

				// here do stuff with the client handshake
				log.Println(log.TRACE, "Handing connection to RPC layer")
				s.RPCServ.ServeCodec(codec)
			}()
		case register := <-s.registeredChan:
			if register {
				s.register()
			} else {
				s.unregister()
			}
		case <-s.shutdownChan:
			s.shutdown()
		case _ = <-s.doneChan:
			break loop
		}
	}
}
예제 #4
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()
		}
	}
}