feat(backend): added support of message size
This commit is contained in:
parent
50d310ba2b
commit
d06bd8769f
3 changed files with 1823 additions and 1296 deletions
|
|
@ -1,35 +1,138 @@
|
|||
package messages
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RawMessage is a not decoded message
|
||||
type RawMessage struct {
|
||||
tp uint64
|
||||
size uint64
|
||||
data []byte
|
||||
meta *message
|
||||
}
|
||||
|
||||
func (m *RawMessage) Encode() []byte {
|
||||
return m.data
|
||||
}
|
||||
|
||||
func (m *RawMessage) TypeID() int {
|
||||
return int(m.tp)
|
||||
}
|
||||
|
||||
func (m *RawMessage) Meta() *message {
|
||||
return m.meta
|
||||
}
|
||||
|
||||
func WriteSize(size uint64, buf []byte, p int) {
|
||||
var m uint64 = 255
|
||||
for i := 0; i < 3; i++ {
|
||||
buf[p+i] = byte(size & m)
|
||||
size = size >> 8
|
||||
}
|
||||
fmt.Println(buf)
|
||||
}
|
||||
|
||||
func ReadSize(reader io.Reader) (uint64, error) {
|
||||
buf := make([]byte, 3)
|
||||
n, err := io.ReadFull(reader, buf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n != 3 {
|
||||
return 0, fmt.Errorf("read only %d of 3 size bytes", n)
|
||||
}
|
||||
var size uint64
|
||||
for i, b := range buf {
|
||||
size += uint64(b) << (8 * i)
|
||||
}
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func messageHasSize(msgType uint64) bool {
|
||||
return !(msgType == 80 || msgType == 81 || msgType == 82)
|
||||
}
|
||||
|
||||
func ReadBatchReader(reader io.Reader, messageHandler func(Message)) error {
|
||||
var index uint64
|
||||
var timestamp int64
|
||||
var (
|
||||
index uint64
|
||||
timestamp int64
|
||||
version uint64
|
||||
)
|
||||
log.Println("new batch")
|
||||
|
||||
for {
|
||||
msg, err := ReadMessage(reader)
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "Unknown message code:") {
|
||||
code := strings.TrimPrefix(err.Error(), "Unknown message code: ")
|
||||
msg, err = DecodeExtraMessage(code, reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't decode msg: %s", err)
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(err, "Batch Message decoding error on message with index %v", index)
|
||||
// Read message type
|
||||
msgType, err := ReadUint(reader)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("can't read message type: %s", err)
|
||||
}
|
||||
log.Printf("message type: %d", msgType)
|
||||
|
||||
var msg Message
|
||||
if version > 0 && messageHasSize(msgType) {
|
||||
// Read message size if it's new protocol version
|
||||
msgSize, err := ReadSize(reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't read message size: %s", err)
|
||||
}
|
||||
// Read raw message (bytes)
|
||||
log.Println("size:", msgSize)
|
||||
buf := make([]byte, msgSize)
|
||||
_, err = io.ReadFull(reader, buf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't read raw body: %s", err)
|
||||
}
|
||||
// Create message object
|
||||
msg = &RawMessage{
|
||||
tp: msgType,
|
||||
size: msgSize,
|
||||
data: buf,
|
||||
meta: &message{},
|
||||
}
|
||||
// Temp code
|
||||
msg, err = ReadMessage(msgType, bytes.NewReader(buf))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
msg, err = ReadMessage(msgType, reader)
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "Unknown message code:") {
|
||||
code := strings.TrimPrefix(err.Error(), "Unknown message code: ")
|
||||
msg, err = DecodeExtraMessage(code, reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't decode msg: %s", err)
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(err, "Batch Message decoding error on message with index %v", index)
|
||||
}
|
||||
}
|
||||
msg = transformDeprecated(msg)
|
||||
}
|
||||
msg = transformDeprecated(msg)
|
||||
|
||||
isBatchMeta := false
|
||||
switch m := msg.(type) {
|
||||
case *BatchMetadata:
|
||||
if index != 0 { // Might be several 0-0 BatchMeta in a row without a error though
|
||||
return errors.New("Batch Meta found at the end of the batch")
|
||||
}
|
||||
index = m.PageNo<<32 + m.FirstIndex // 2^32 is the maximum count of messages per page (ha-ha)
|
||||
timestamp = m.Timestamp
|
||||
version = m.Version
|
||||
isBatchMeta = true
|
||||
log.Printf("new batch version: %d", version)
|
||||
|
||||
case *BatchMeta: // Is not required to be present in batch since IOS doesn't have it (though we might change it)
|
||||
if index != 0 { // Might be several 0-0 BatchMeta in a row without a error though
|
||||
return errors.New("Batch Meta found at the end of the batch")
|
||||
|
|
|
|||
|
|
@ -1498,22 +1498,6 @@ func (msg *CustomIssue) TypeID() int {
|
|||
return 64
|
||||
}
|
||||
|
||||
type PageClose struct {
|
||||
message
|
||||
}
|
||||
|
||||
func (msg *PageClose) Encode() []byte {
|
||||
buf := make([]byte, 1)
|
||||
buf[0] = 65
|
||||
p := 1
|
||||
|
||||
return buf[:p]
|
||||
}
|
||||
|
||||
func (msg *PageClose) TypeID() int {
|
||||
return 65
|
||||
}
|
||||
|
||||
type AssetCache struct {
|
||||
message
|
||||
URL string
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue