duanbei7035 2018-11-21 08:10
浏览 56
已采纳

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

I am using google's protocol buffers to send data from client to server.

Client and server both are written in Golang.

I think it uses plain tcp to send data from client to server.

Sample client code:

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
", err.Error())
        return
    }
    sentBytes, err := conn.Write(data)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error sending bytes to serve: %s
", err.Error())
        return
    }
    fmt.Printf("Sent %d bytes
", 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)
    }
}

How to send data from client to server via HTTP using protocol buffers in Golang?

  • 写回答

1条回答 默认 最新

  • dongliqin6939 2018-11-21 12:16
    关注

    I successfully implemented protobuff vai http.

    Credits: 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
    ", len(message))
    }
    
    func main() {
        fmt.Println("Starting client..")
        transaction := getFakeTransaction()
        for {
            sendMessage(transaction)
            // time.Sleep(1 * time.Second)
        }
    }
    

    Sample Server:

    func printMessage(t *proto.Transaction) {
        clientId := t.GetClientId()
        clientName := t.GetClientName()
        items := t.GetItems()
        fmt.Printf("ClientId: %s, ClientName: %s, Items: %s
    ", 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)
    
    }
    

    Sample Protofile:

    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;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 关于#html5#的问题:H5页面用户手机返回的时候跳转到指定页面例如(语言-javascript)
  • ¥15 无法使用此凭据登录,因为你的域不可用,如何解决?(标签-Windows)
  • ¥15 yolov9的训练时间
  • ¥15 二叉树遍历没有报错但无法正常运行
  • ¥15 在linux系统下vscode运行robocup3d上场球员报错
  • ¥15 maven环境配置后无法运行mvn -v
  • ¥15 Python语言实验
  • ¥15 SAP HANA SQL 增加合计行
  • ¥20 用C#语言解决一个英文打字练习器,有偿
  • ¥15 srs-sip外部服务 webrtc支持H265格式