Golang + Protobuf 통신 프로토콜 구성

2807 단어
Golang은 인터넷 통신을 쓰는 데 매우 편리하다. 그 중에서 메시지 통신은 크로스 언어의 Protobuf를 사용할 수 있다.본고는 Protobuf를 사용하여 Golang의 통신 프로토콜을 구축하는 방법을 설명한다.
(1)Protobuf는 protoc가 필요합니다. 이것은github에서 컴파일을 다운로드하면 설치할 수 있습니다.디비안 계열도 apt를 통해 설치할 수 있습니다.(2) 두 번째는 go 플러그인입니다. 이 플러그인은 원본 코드를 다운로드한 후 gobuild과 go install을 실행하면 $GOPATH 경로 아래에 설치하고 이 폴더를 $PATH에 추가하면 사용할 수 있습니다.(3) 프로토 파일을 작성하고 자세한 내용은 공식 문서를 참고하십시오.이렇게 보입니다.
// poster.proto
package poster;

message Mail {
    required bytes type = 1;
    required bytes md5 = 2;
    required bytes path = 3;
}

이상은 socket에서 사용한 메시지 형식입니다. 메시지의 type,md5의 값, path 경로와 파일의 크기를 각각 정의하면 다음md5 검사, 리셋 기능에 사용할 수 있고 메시지 형식에 따라 서로 다른 신호를 정의할 수 있습니다.여기에 bytes를 사용하는 것은 필수적인 것이 아니다. 단지 나는 내 코드에서 각 필드의 길이를 각각 정의할 뿐이다. byte는 나에게 더욱 직관적이다.
그리고 그것을 골롱의 라이브러리 import로 바꾸어 자신의 코드에 생성하는 명령은 다음과 같다.
protoc --go_out=. poster.proto

그리고 나는 포스터를 얻게 될 거야.pb.go 파일입니다. 그 다음에 제 코드에 import 라이브러리를 넣을 수 있습니다.그러나 이 라이브러리는 형식을 정의하고 정보를 읽는 기능을 제공할 뿐이다.정보를 protobuf로 포장하거나 해제하려면 다른 라이브러리에서 지원해야 합니다. 다음 명령을 통해 달성할 수 있습니다.
go get github.com/golang/protobuf/proto

가장 기본적인 Marshal과 Unmarshal 방법에 대해서는 설명을 하지 않겠습니다. 하지만 여기에 struct와protoc가 협조하여 사용하는 예를 붙이지만 복사하고 붙이지 마십시오. 여기에 utils의 라이브러리가 있는데 주로 int64를byte로 바꾸는 방법입니다.또한 프로토 파일에서 세 개의 필드가byte 형식으로 정의되었기 때문에 원래의 형식을byte 형식으로 먼저 바꾸지만 struct에서는 적합한 형식으로 호출하기 편리합니다.
//            socket                 
const (
    typeSize   = 8
    md5Size    = 32
    pathSize   = 80
    bufferSize = 126
)

type msgBuffer struct {
    bufType  int
    bufMd5   string
    bufPath  string
}
// 
func (msgBuf *msgBuffer) NewMsg() []byte {

    bufType := make([]byte, typeSize)
    bufMd5 := make([]byte, md5Size)
    bufPath := make([]byte, pathSize)

    copy(bufType, utils.Int64ToByte(int64(msgBuf.bufType)))
    copy(bufMd5, []byte(msgBuf.bufMd5))
    copy(bufPath, []byte(msgBuf.bufPath))

    dataText := &poster.Mail {
        Type: bufType,
        Md5 : bufMd5,
        Path: bufPath,
    }

    data, err := proto.Marshal(dataText)
    checkError(err)
    return data
} 

이 데이터는 바로 마음대로 전송할 수 있는byte array입니다.마지막으로 수신자는 아래와 같이 메시지를 해제하고 우호적으로 호출할 수 있다.(utils.FirstNull은 첫 번째 byte에서 시작해서 마지막 ASCII가 0이 아닌 문자를 자동으로 캡처합니다. 고정된 길이가 설정되어 있고,value의 길이가 그렇게 길지 않으면,null을 채웁니다.)
func msgParser(data []byte) *msgBuffer {
    dataText := &poster.Mail{}
    err := proto.Unmarshal(data, dataText)
    checkError(err)

    msgType := utils.ByteToInt64(dataText.GetType())
    msgMd5 := string(dataText.GetMd5())
    msgPath := string(dataText.GetPath()[:utils.FirstNull(dataText.GetPath())])

    msg := &msgBuffer{int(msgType), msgMd5, msgPath}
    return msg
}

전체 절차는 매우 간단하다. 가장 번거로운 점은 아마도 프로토퍼가 컴파일링과 설치 설정을 다운로드하는 것이다.
(끝)

좋은 웹페이지 즐겨찾기