protobuf介绍这里不在叙述,可自行百度,有空再补.
安装 protobuf
使用release版本,编译安装
#下载
sudo apt-get install autoconf automake libtool curl make g++ unzip
git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
#编译
./configure
make
make check
#安装
sudo make install
sudo ldconfig
# 检查
protoc -h
安装go插件
go get -u -v github.com/golang/protobuf/proto
go get -u -v github.com/golang/protobuf/protoc-gen-go
编译
cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go/
go install
此时会在$GOPATH/bin/
生成二进制文件
ls $GOPATH/bin/protoc-gen-go
/home/jinchunguang/go/bin/protoc-gen-go
protoc --go_out=plugins=grpc:. *.proto
➜ pro tree
.
├── service.pb.go
└── service.proto
测试
主要代码
contact_book.proto
syntax = "proto3";
package pro;
message Person {
int32 id = 1;
string name = 2;
string phone = 3;
}
message ContactBook {
repeated Person persons = 1;
}
message_info.proto
syntax = "proto3";
package pro;
message Message{
string message = 1;
int32 length = 2;
}
main.go
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"go-protobuf-demo/pro"
"io/ioutil"
"os"
)
func write() {
book := &pro.ContactBook{}
book.Persons = append(book.Persons, &pro.Person{Id: 1, Name: "小张", Phone: "130-1111-5678"});
book.Persons = append(book.Persons, &pro.Person{Id: 2, Name: "小红", Phone: "131-2222-5678",});
book.Persons = append(book.Persons, &pro.Person{Id: 3, Name: "小明", Phone: "172-3333-5678",});
data, _ := proto.Marshal(book);
fmt.Println("编码数据: ", data)
ioutil.WriteFile("./cmd/book.data", data, os.ModePerm);
}
func read() {
data, _ := ioutil.ReadFile("./cmd/book.data")
book := &pro.ContactBook{};
proto.Unmarshal(data, book);
fmt.Println("解码数据: ", book.Persons)
for _, v := range book.Persons {
fmt.Println(v.Id, v.Name, v.Phone)
}
}
func main() {
write()
read()
}
client.go
/**
* @Author : jinchunguang
* @Date : 19-11-6 下午4:52
* @Project : go-protobuf-demo
*/
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"go-protobuf-demo/pro"
"net"
)
func main() {
var err error
var msg string
// 收集消息
fmt.Println("请输入短消息:")
if _, err := fmt.Scanf("%s", &msg); err != nil {
fmt.Printf("%s\n", err)
return
}
// 编码数据
user := &pro.Message{
Message: msg,
Length: *proto.Int(len(msg)),
}
pbData, err := proto.Marshal(user)
if err != nil {
fmt.Println("proto marshal err ", err)
return
}
// 连接server
address := "localhost:6600"
conn, err := net.Dial("tcp", address);
defer conn.Close()
if err != nil {
fmt.Println("net dial err ", err)
return
}
// 发送数据
n, err := conn.Write(pbData)
if err != nil {
fmt.Println("net write err ", err)
return
}
fmt.Println("conn write len:", n)
}
server.go
/**
* @Author : jinchunguang
* @Date : 19-11-6 下午4:52
* @Project : go-protobuf-demo
*/
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"go-protobuf-demo/pro"
"io"
"net"
)
func main() {
address := "localhost:6600"
listener, err := net.Listen("tcp", address)
if err != nil {
fmt.Errorf("listen err:", err)
}
fmt.Println("[START] Server listenner: ", address)
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("conn err:", err)
return
}
// 异步执行请求业务
go processing(conn)
}
}
func processing(conn net.Conn) {
// 延迟关闭
defer conn.Close()
// 缓冲
buf := make([]byte, 4096)
for {
len, err := conn.Read(buf)
// 读取结束
if err == io.EOF {
return
}
if err != nil {
fmt.Println("conn read err:", err)
return
}
user := &pro.Message{}
err = proto.Unmarshal(buf[:len], user)
if err != nil {
fmt.Println("proto unmarshal err:", err)
return
}
fmt.Println("receive data:%v ip:%v ", user.Message, conn.RemoteAddr())
}
}
build.sh
#!/usr/bin/env bash
echo "生成GO文件"
cd pro
protoc --go_out=plugins=grpc:. *.proto
# 构建 file 执行文件
echo "生成执行文件"
cd ..
go build -o cmd/file file/main.go
go build -o cmd/pb_server cs/server/server.go
go build -o cmd/pb_client cs/client/client.go
未完待续.
https://github.com/jinchunguang/github-actions-demo
有疑问加站长微信联系(非本文作者)