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
// 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:
			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,
			}

			encoder := bsonrpc.NewEncoder(conn)
			err := encoder.Encode(sh)
			if err != nil {
				log.Println(log.ERROR, "Failed to encode server handshake", err.Error())
				continue
			}
			if !s.Registered {
				log.Println(log.ERROR, "Connection attempted while unregistered. Closing connection")
				conn.Close()
				continue
			}

			// read the client handshake
			var ch skynet.ClientHandshake
			decoder := bsonrpc.NewDecoder(conn)
			err = decoder.Decode(&ch)
			if err != nil {
				log.Println(log.ERROR, "Error calling bsonrpc.NewDecoder: "+err.Error())
				continue
			}

			// here do stuff with the client handshake
			go func() {
				s.RPCServ.ServeCodec(bsonrpc.NewServerCodec(conn))
			}()
		case register := <-s.registeredChan:
			if register {
				s.register()
			} else {
				s.unregister()
			}
		case <-s.shutdownChan:
			s.shutdown()
		case _ = <-s.doneChan:
			break loop
		}
	}
}