예제 #1
0
func (c *Client) write(request *protobuf.Request) chan protobuf.Response {
	data, err := proto.Marshal(request)
	if err != nil {
		log.Printf("Marshaling error: %v\n", err)
		return nil
	}

	length := len(data)
	lengthBytes := make([]byte, 4)
	binary.BigEndian.PutUint32(lengthBytes, uint32(length))

	// Guarantee squential write of length then protobuf on stream
	c.connLock.Lock()
	defer c.connLock.Unlock()
	_, err = c.conn.Write(lengthBytes)
	if err != nil {
		log.Printf("Error writing data: %v\n", err)
		return nil
	}
	_, err = c.conn.Write(data)
	if err != nil {
		log.Printf("Error writing data: %v\n", err)
		return nil
	}

	callback := make(chan protobuf.Response)
	c.pending[request.GetId()] = callback
	return callback
}
예제 #2
0
func (c *Client) Get(key string) (int, string) {
	request := new(protobuf.Request)
	request.Id = proto.String(randomId())
	request.Type = proto.String("get")
	request.Key = proto.String(key)

	callback := c.write(request)
	if callback == nil {
		return -1, ""
	}

	// Block on callback
	response := <-callback
	return int(response.GetResult()), response.GetValue()
}
예제 #3
0
func (s *Server) run() {
	for {
		if conn, err := s.listener.Accept(); err == nil {
			go func(s *Server, conn net.Conn) {
				defer conn.Close()
				log.Println("Connection established with client")
				for {

					data := make([]byte, 4)
					_, err := conn.Read(data)
					if err != nil {
						log.Printf("Error reading length: %v", err)
						return
					}
					length := int(binary.BigEndian.Uint32(data))

					data = make([]byte, length)
					for i := 0; i < length; {
						//Read the data waiting on the connection and put it in the data buffer
						n, err := conn.Read(data[i : length-i])
						i += n
						if err != nil {
							log.Printf("Error reading request: %v", err)
							return
						}
					}
					//Create an struct pointer of type protobuf.Request and protobuf.Response struct
					request := new(protobuf.Request)
					//Convert all the data retrieved into the ProtobufTest.TestMessage struct type
					err = proto.Unmarshal(data[:length], request)
					if err != nil {
						log.Printf("Error in Unmarshalling: %v\n", err)
						return
					}
					response := new(protobuf.Response)
					response.Id = request.Id
					if request.GetType() == "get" {
						result, value := s.Get(request.GetKey())
						response.Result = proto.Int32(int32(result))
						response.Value = proto.String(value)
					} else {
						result, value := s.Set(request.GetKey(), request.GetValue())
						response.Result = proto.Int32(int32(result))
						response.Value = proto.String(value)
					}

					data, err = proto.Marshal(response)
					if err != nil {
						log.Printf("Marshaling error: %v\n", err)
						continue
					}

					length = len(data)
					lengthBytes := make([]byte, 4)
					binary.BigEndian.PutUint32(lengthBytes, uint32(length))
					_, err = conn.Write(lengthBytes)
					if err != nil {
						log.Printf("Error writing data: %v\n", err)
						return
					}
					_, err = conn.Write(data)
					if err != nil {
						log.Printf("Error writing data: %v\n", err)
						return
					}
				}
			}(s, conn)
		} else {
			continue
		}
	}
}