如何通过 http 实现 google 的协议缓冲区

how to implement google's protocol buffers via http

我正在使用 google 的协议缓冲区 将数据从客户端发送到服务器。

客户端和服务端都是用Golang写的

我认为它使用纯 tcp 将数据从 client 发送到 server

示例客户端代码:

func getFakeTransaction() *proto.Transaction {
    transaction := new(proto.Transaction)
    transaction.ClientId = "client_1"
    transaction.ClientName = "Europa"

    items := new(proto.Items)
    items.ItemId = 1
    items.ItemName = "Space suite"
    items.ItemValue = 2000
    transaction.Items = items

    return transaction
}

func readDataFromExternalDatasource() *proto.Transaction {
    return getFakeTransaction()
}

func sentDataToServer(data []byte) {
    conn, err := net.Dial("tcp", "localhost:8080")
    defer conn.Close()
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error while dialing server: %s\n", err.Error())
        return
    }
    sentBytes, err := conn.Write(data)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error sending bytes to serve: %s\n", err.Error())
        return
    }
    fmt.Printf("Sent %d bytes\n", sentBytes)
}

func main() {
    fmt.Println("Starting client..")
    data := readDataFromExternalDatasource()
    dataInByteArr, err := protoc.Marshal(data)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error while Marshal data: %s", err.Error())
    }
    for {
        sentDataToServer(dataInByteArr)
        time.Sleep(1000)
    }
}

如何在 Golang 中使用协议缓冲区通过 HTTP 从客户端向服务器发送数据?

成功实现 protobuff vai http.

学分https://jacobmartins.com/2016/05/24/practical-golang-using-protobuffs/

Sample_Client:

func getFakeTransaction() *proto.Transaction {
    transaction := new(proto.Transaction)
    transaction.ClientId = "client_1"
    transaction.ClientName = "Europa"

    items := new(proto.Items)
    items.ItemId = 1
    items.ItemName = "Space suite"
    items.ItemValue = 2000
    transaction.Items = items

    return transaction
}

func sendMessage(transaction *proto.Transaction) {
    message, err := protoc.Marshal(transaction)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error while marshaling message: %s", err.Error())
        os.Exit(1)
    }

    _, err = http.Post("http://localhost:8080", "", bytes.NewBuffer(message))
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error while post request to server: %s", err.Error())
        os.Exit(1)
    }
    fmt.Printf("Sent %d bytes to server\n", len(message))
}

func main() {
    fmt.Println("Starting client..")
    transaction := getFakeTransaction()
    for {
        sendMessage(transaction)
        // time.Sleep(1 * time.Second)
    }
}

示例服务器:

func printMessage(t *proto.Transaction) {
    clientId := t.GetClientId()
    clientName := t.GetClientName()
    items := t.GetItems()
    fmt.Printf("ClientId: %s, ClientName: %s, Items: %s\n", clientId, clientName, items)
}

func main() {
    fmt.Println("Staring server..")
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        message, err := ioutil.ReadAll(r.Body)
        if err != nil {
            fmt.Fprintf(os.Stderr, "Error while reading data from client: ", err.Error())
            return
        }
        transaction := new(proto.Transaction)
        // protoc.Unmarshal(message, &transaction)
        if err = transaction.XXX_Unmarshal(message); err != nil {
            fmt.Fprintf(os.Stderr, "Error while unmarshaling client message: %s", err.Error())
            return
        }
        printMessage(transaction)
    })
    http.ListenAndServe(":8080", nil)

}

原型文件:

syntax="proto3";

package proto;

enum Status {
    SUCCESS = 0;
    INPROGRESS = 1;
    FAILED = 2;
}

message Items {
    int32 itemId = 1;
    string itemName = 2;
    int32 itemValue = 3;
    Status status = 4;
}

message Transaction {
    string clientId = 1;
    string clientName = 2;
    Items items = 3;
}