Răsfoiți Sursa

change conn package struct

Joyit 1 lună în urmă
părinte
comite
2fd8eb1182
3 a modificat fișierele cu 286 adăugiri și 414 ștergeri
  1. 11 208
      conn/tcp2/tcp2.go
  2. 254 0
      conn/util.go
  3. 21 206
      conn/ws2/ws2.go

+ 11 - 208
conn/tcp2/tcp2.go

@@ -8,7 +8,6 @@ import (
 	"io"
 	"log"
 	"net"
-	"slices"
 	"strings"
 	"time"
 
@@ -306,48 +305,11 @@ func (c *Tcp2) ReadRawPackage(deadline int) (buf []byte, recycle bool, err error
 // 发送Auth信息
 // 建立连接后第一个发送的消息
 func (c *Tcp2) WriteAuthInfo(channel string, auth []byte) (err error) {
-	protoLen := len(PROTO)
-	if protoLen > 0xFF {
-		return errors.New("length of protocol over")
-	}
-
-	channelLen := len(channel)
-	if channelLen > 0xFFFF {
-		return errors.New("length of channel over")
-	}
-	// id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
-	dlen := 2 + 1 + protoLen + 1 + 1 + 2 + channelLen + len(auth)
-	buf := pool.Get(dlen)
-	index := 0
-	binary.BigEndian.PutUint16(buf[index:index+2], config.ID_AUTH)
-	index += 2
-
-	buf[index] = byte(protoLen)
-	index++
-	copy(buf[index:index+protoLen], []byte(PROTO))
-	index += protoLen
-
-	buf[index] = VERSION
-	index++
-
-	if c.compress {
-		buf[index] = 0x01
-	} else {
-		buf[index] = 0
-	}
-	index++
-
-	binary.BigEndian.PutUint16(buf[index:index+2], uint16(channelLen))
-	index += 2
-
-	copy(buf[index:index+channelLen], []byte(channel))
-	index += channelLen
-	copy(buf[index:], auth)
+	buf := conn.AuthPackageEncode(PROTO, VERSION, channel, auth, c.compress)
 	return c.WriteRawPackage(buf, true)
 }
 
 // 获取Auth信息
-// id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
 func (c *Tcp2) ReadAuthInfo() (proto string, version uint8, channel string, auth []byte, err error) {
 	defer func() {
 		if r := recover(); r != nil {
@@ -359,156 +321,39 @@ func (c *Tcp2) ReadAuthInfo() (proto string, version uint8, channel string, auth
 	if err != nil {
 		return
 	}
-	if recycle {
-		defer pool.Put(msg)
-	}
-	msgLen := len(msg)
-	if msgLen < 9 {
-		err = errors.New("wrong message length")
-		return
-	}
-	index := 0
-	id := binary.BigEndian.Uint16(msg[index : index+2])
-	if id != config.ID_AUTH {
-		err = fmt.Errorf("wrong message id: %d", id)
-		return
-	}
-	index += 2
-
-	protoLen := int(msg[index])
-	if protoLen < 2 {
-		err = errors.New("wrong proto length")
+	var compress bool
+	proto, version, compress, channel, auth, err = conn.AuthPackageDecode(msg, recycle)
+	if err != nil {
 		return
 	}
-	index++
-	proto = string(msg[index : index+protoLen])
 	if proto != PROTO {
 		err = fmt.Errorf("wrong proto: %s", proto)
 		return
 	}
-	index += protoLen
-
-	version = msg[index]
 	if version != VERSION {
 		err = fmt.Errorf("require version %d, get version: %d", VERSION, version)
 		return
 	}
-	index++
-
-	c.compress = (msg[index] & 0x01) != 0
-	index++
-
-	channelLen := int(binary.BigEndian.Uint16(msg[index : index+2]))
-	if channelLen < 2 {
-		err = errors.New("wrong channel length")
-		return
-	}
-	index += 2
-	channel = string(msg[index : index+channelLen])
-	index += channelLen
-
-	if recycle {
-		auth = slices.Clone(msg[index:])
-	} else {
-		auth = msg[index:]
-	}
+	c.compress = compress
 	return
 }
 
 // 发送请求数据包到网络
 func (c *Tcp2) WriteRequest(id uint16, cmd string, data []byte) error {
-	// 为了区分请求还是响应包,命令字符串不能超过127个字节
-	cmdLen := len(cmd)
-	if cmdLen > 0x7F {
-		return errors.New("command length is more than 0x7F")
-	}
-	dlen := len(data)
-	if c.compress && dlen > 0 {
-		compressedData, ok, _ := util.CompressData(data)
-		// id(uint16)+cmdLen(byte)+len(cmd)+option(byte)+len(data)
-		ddlen := 2 + 1 + cmdLen + 1 + len(compressedData)
-		buf := pool.Get(ddlen)
-		index := 0
-		binary.BigEndian.PutUint16(buf[index:index+2], id)
-		index += 2
-
-		buf[index] = byte(cmdLen)
-		index++
-		copy(buf[index:index+cmdLen], cmd)
-		index += cmdLen
-
-		if ok {
-			buf[index] = 0x01
-			if c.cf.PrintMsg {
-				log.Println("[CompressData]", len(data), "->", len(compressedData))
-			}
-		} else {
-			buf[index] = 0
-		}
-		index++
-
-		copy(buf[index:], compressedData)
-		return c.WriteRawPackage(buf, true)
-	} else {
-		ddlen := 2 + 1 + cmdLen + dlen
-		buf := pool.Get(ddlen)
-		index := 0
-		binary.BigEndian.PutUint16(buf[index:index+2], id)
-		index += 2
-		buf[index] = byte(cmdLen)
-		index++
-		copy(buf[index:index+cmdLen], cmd)
-		index += cmdLen
-		copy(buf[index:], data)
-		return c.WriteRawPackage(buf, true)
-	}
+	buf := conn.RequestPackageEncode(id, cmd, data, c.compress, c.cf)
+	return c.WriteRawPackage(buf, true)
 }
 
 // 发送响应数据包到网络
 // 网络格式:[id, stateCode, data]
 func (c *Tcp2) WriteResponse(id uint16, state uint8, data []byte) error {
-	dlen := len(data)
-	if c.compress && dlen > 0 {
-		compressedData, ok, _ := util.CompressData(data)
-		ddlen := 2 + 1 + 1 + len(compressedData)
-		buf := pool.Get(ddlen)
-		index := 0
-		binary.BigEndian.PutUint16(buf[index:index+2], id)
-		index += 2
-
-		buf[index] = state | 0x80
-		index++
-
-		if ok {
-			buf[index] = 0x001
-			if c.cf.PrintMsg {
-				log.Println("[CompressData]", len(data), "->", len(compressedData))
-			}
-		} else {
-			buf[index] = 0
-		}
-		index++
-
-		copy(buf[index:], compressedData)
-		return c.WriteRawPackage(buf, true)
-	} else {
-		ddlen := 2 + 1 + len(data)
-		buf := pool.Get(ddlen)
-		index := 0
-		binary.BigEndian.PutUint16(buf[index:index+2], id)
-		index += 2
-		buf[index] = state | 0x80
-		index++
-		copy(buf[index:], data)
-		return c.WriteRawPackage(buf, true)
-	}
+	buf := conn.ResponsePackageEncode(id, state, data, c.compress, c.cf)
+	return c.WriteRawPackage(buf, true)
 }
 
 // 发送ping包
 func (c *Tcp2) WritePing(id uint16) error {
-	buf := pool.Get(2)
-	index := 0
-	binary.BigEndian.PutUint16(buf[index:index+2], id)
+	buf := conn.PingPackageEncode(id)
 	return c.WriteRawPackage(buf, true)
 }
 
@@ -518,49 +363,7 @@ func (c *Tcp2) ReadMessage(deadline int) (msgType conn.MsgType, id uint16, cmd s
 	if err != nil {
 		return
 	}
-	if recycle {
-		defer pool.Put(msg)
-	}
-	msgLen := len(msg)
-	id = binary.BigEndian.Uint16(msg[0:2])
-	// ping信息
-	if msgLen == 2 {
-		msgType = conn.PingMsg
-		return
-	}
-
-	if id > config.ID_MAX {
-		err = fmt.Errorf("wrong message id: %d", id)
-		return
-	}
-
-	cmdx := msg[2]
-	if (cmdx & 0x80) == 0 {
-		// 请求包
-		msgType = conn.RequestMsg
-		cmdLen := int(cmdx)
-		cmd = string(msg[3 : cmdLen+3])
-		data = msg[cmdLen+3:]
-	} else {
-		// 响应数据包
-		msgType = conn.ResponseMsg
-		state = cmdx & 0x7F
-		data = msg[3:]
-	}
-	dataLen := len(data)
-	if c.compress && dataLen > 1 {
-		var ok bool
-		data, ok, err = util.UncompressData(data)
-		if !ok && recycle {
-			data = slices.Clone(data)
-		}
-		if ok && c.cf.PrintMsg {
-			log.Println("[UncompressData]", dataLen, "->", len(data))
-		}
-	} else if recycle && dataLen > 0 {
-		data = slices.Clone(data)
-	}
-	return
+	return conn.PackageDecode(msg, recycle, c.compress, c.cf)
 }
 
 // 获取远程的地址

+ 254 - 0
conn/util.go

@@ -0,0 +1,254 @@
+package conn
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"log"
+	"slices"
+
+	"git.me9.top/git/tinymq/config"
+	"git.me9.top/git/tinymq/util"
+	"git.me9.top/git/tinymq/util/pool"
+)
+
+// 验证包编码,其中输出的数据需要回收
+func AuthPackageEncode(proto string, version uint8, channel string, auth []byte, compress bool) (buf []byte) {
+	protoLen := len(proto)
+	protoLenMax := 0xFF
+	if protoLen > protoLenMax {
+		proto = proto[0:protoLenMax]
+		protoLen = protoLenMax
+	}
+
+	channelLen := len(channel)
+	channelLenMax := 0xFFFF
+	if channelLen > channelLenMax {
+		channel = channel[0:channelLenMax]
+		channelLen = channelLenMax
+	}
+	// id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
+	dlen := 2 + 1 + protoLen + 1 + 1 + 2 + channelLen + len(auth)
+	buf = pool.Get(dlen)
+	index := 0
+	binary.BigEndian.PutUint16(buf[index:index+2], config.ID_AUTH)
+	index += 2
+
+	buf[index] = byte(protoLen)
+	index++
+	copy(buf[index:index+protoLen], []byte(proto))
+	index += protoLen
+
+	buf[index] = version
+	index++
+
+	if compress {
+		buf[index] = 0x01
+	} else {
+		buf[index] = 0
+	}
+	index++
+
+	binary.BigEndian.PutUint16(buf[index:index+2], uint16(channelLen))
+	index += 2
+
+	copy(buf[index:index+channelLen], []byte(channel))
+	index += channelLen
+	copy(buf[index:], auth)
+	return
+}
+
+// 验证包解码
+// id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
+func AuthPackageDecode(msg []byte, recycle bool) (proto string, version uint8, compress bool, channel string, auth []byte, err error) {
+	if recycle {
+		defer pool.Put(msg)
+	}
+	msgLen := len(msg)
+	if msgLen < 9 {
+		err = errors.New("wrong message length")
+		return
+	}
+	index := 0
+	id := binary.BigEndian.Uint16(msg[index : index+2])
+	if id != config.ID_AUTH {
+		err = fmt.Errorf("wrong message id: %d", id)
+		return
+	}
+	index += 2
+
+	protoLen := int(msg[index])
+	if protoLen < 2 {
+		err = errors.New("wrong proto length")
+		return
+	}
+	index++
+	proto = string(msg[index : index+protoLen])
+	index += protoLen
+
+	version = msg[index]
+	index++
+
+	compress = (msg[index] & 0x01) != 0
+	index++
+
+	channelLen := int(binary.BigEndian.Uint16(msg[index : index+2]))
+	if channelLen < 2 {
+		err = errors.New("wrong channel length")
+		return
+	}
+	index += 2
+	channel = string(msg[index : index+channelLen])
+	index += channelLen
+
+	if recycle {
+		auth = slices.Clone(msg[index:])
+	} else {
+		auth = msg[index:]
+	}
+	return
+}
+
+// 请求包
+func RequestPackageEncode(id uint16, cmd string, data []byte, compress bool, cf *config.Config) (buf []byte) {
+	// 为了区分请求还是响应包,命令字符串不能超过127个字节
+	cmdLenMax := 0x7F
+	cmdLen := len(cmd)
+	if cmdLen > cmdLenMax {
+		cmd = cmd[0:cmdLenMax]
+		cmdLen = cmdLenMax
+	}
+	dlen := len(data)
+	if compress && dlen > 0 {
+		compressedData, ok, _ := util.CompressData(data)
+		// id(uint16)+cmdLen(byte)+len(cmd)+option(byte)+len(data)
+		ddlen := 2 + 1 + cmdLen + 1 + len(compressedData)
+		buf = pool.Get(ddlen)
+		index := 0
+		binary.BigEndian.PutUint16(buf[index:index+2], id)
+		index += 2
+
+		buf[index] = byte(cmdLen)
+		index++
+		copy(buf[index:index+cmdLen], cmd)
+		index += cmdLen
+
+		if ok {
+			buf[index] = 0x01
+			if cf.PrintMsg {
+				log.Println("[CompressData]", len(data), "->", len(compressedData))
+			}
+		} else {
+			buf[index] = 0
+		}
+		index++
+
+		copy(buf[index:], compressedData)
+
+	} else {
+		ddlen := 2 + 1 + cmdLen + dlen
+		buf = pool.Get(ddlen)
+		index := 0
+		binary.BigEndian.PutUint16(buf[index:index+2], id)
+		index += 2
+		buf[index] = byte(cmdLen)
+		index++
+		copy(buf[index:index+cmdLen], cmd)
+		index += cmdLen
+		copy(buf[index:], data)
+	}
+	return
+}
+
+// 响应数据包
+// 网络格式:[id, stateCode, data]
+func ResponsePackageEncode(id uint16, state uint8, data []byte, compress bool, cf *config.Config) (buf []byte) {
+	dlen := len(data)
+	if compress && dlen > 0 {
+		compressedData, ok, _ := util.CompressData(data)
+		ddlen := 2 + 1 + 1 + len(compressedData)
+		buf = pool.Get(ddlen)
+		index := 0
+		binary.BigEndian.PutUint16(buf[index:index+2], id)
+		index += 2
+
+		buf[index] = state | 0x80
+		index++
+
+		if ok {
+			buf[index] = 0x001
+			if cf.PrintMsg {
+				log.Println("[CompressData]", len(data), "->", len(compressedData))
+			}
+		} else {
+			buf[index] = 0
+		}
+		index++
+
+		copy(buf[index:], compressedData)
+	} else {
+		ddlen := 2 + 1 + len(data)
+		buf = pool.Get(ddlen)
+		index := 0
+		binary.BigEndian.PutUint16(buf[index:index+2], id)
+		index += 2
+		buf[index] = state | 0x80
+		index++
+		copy(buf[index:], data)
+	}
+	return
+}
+
+func PingPackageEncode(id uint16) (buf []byte) {
+	buf = pool.Get(2)
+	index := 0
+	binary.BigEndian.PutUint16(buf[index:index+2], id)
+	return
+}
+
+// 解析收到的数据包
+func PackageDecode(msg []byte, recycle bool, compress bool, cf *config.Config) (msgType MsgType, id uint16, cmd string, state uint8, data []byte, err error) {
+	if recycle {
+		defer pool.Put(msg)
+	}
+	msgLen := len(msg)
+	id = binary.BigEndian.Uint16(msg[0:2])
+	// ping信息
+	if msgLen == 2 {
+		msgType = PingMsg
+		return
+	}
+
+	if id > config.ID_MAX {
+		err = fmt.Errorf("wrong message id: %d", id)
+		return
+	}
+
+	cmdx := msg[2]
+	if (cmdx & 0x80) == 0 {
+		// 请求包
+		msgType = RequestMsg
+		cmdLen := int(cmdx)
+		cmd = string(msg[3 : cmdLen+3])
+		data = msg[cmdLen+3:]
+	} else {
+		// 响应数据包
+		msgType = ResponseMsg
+		state = cmdx & 0x7F
+		data = msg[3:]
+	}
+	dataLen := len(data)
+	if compress && dataLen > 1 {
+		var ok bool
+		data, ok, err = util.UncompressData(data)
+		if !ok && recycle {
+			data = slices.Clone(data)
+		}
+		if ok && cf.PrintMsg {
+			log.Println("[UncompressData]", dataLen, "->", len(data))
+		}
+	} else if recycle && dataLen > 0 {
+		data = slices.Clone(data)
+	}
+	return
+}

+ 21 - 206
conn/ws2/ws2.go

@@ -2,7 +2,6 @@ package ws2
 
 import (
 	"crypto/rand"
-	"encoding/binary"
 	"errors"
 	"fmt"
 	"log"
@@ -208,7 +207,6 @@ func Dial(cf *config.Config, scheme string, addr string, path string, hash strin
 }
 
 // 发送数据到网络
-// 如果有加密函数的话会直接修改源数据
 func (c *Ws2) WriteRawPackage(buf []byte, recycle bool) (err error) {
 	if recycle {
 		defer pool.Put(buf)
@@ -222,56 +220,25 @@ func (c *Ws2) WriteRawPackage(buf []byte, recycle bool) (err error) {
 
 // 从连接中读取数据包
 // recycle 指示是否需要手动将缓存放回内存池
-func (c *Ws2) ReadRawPackage(deadline int) (msg []byte, recycle bool, err error) {
+func (c *Ws2) ReadRawPackage(deadline int) (buf []byte, recycle bool, err error) {
 	err = c.conn.SetReadDeadline(time.Now().Add(time.Millisecond * time.Duration(deadline)))
 	if err != nil {
 		return
 	}
-	_, msg, err = c.conn.ReadMessage()
+	_, buf, err = c.conn.ReadMessage()
+	if err != nil {
+		return
+	}
+	if c.cipher != nil {
+		c.cipher.Decrypt(buf, buf)
+	}
 	return
 }
 
 // 发送Auth信息
 // 建立连接后第一个发送的消息
 func (c *Ws2) WriteAuthInfo(channel string, auth []byte) (err error) {
-	protoLen := len(PROTO)
-	if protoLen > 0xFF {
-		return errors.New("length of protocol over")
-	}
-	channelLen := len(channel)
-	if channelLen > 0xFFFF {
-		return errors.New("length of channel over")
-	}
-	// id(65502)+proto(string)+version(uint8)+option(byte)+channel(string)+auth([]byte)
-	dlen := 2 + 1 + protoLen + 1 + 1 + 2 + channelLen + len(auth)
-	index := 0
-
-	// buf := make([]byte, dlen)
-	buf := pool.Get(dlen)
-	binary.BigEndian.PutUint16(buf[index:index+2], config.ID_AUTH)
-	index += 2
-
-	buf[index] = byte(protoLen)
-	index++
-	copy(buf[index:index+protoLen], []byte(PROTO))
-	index += protoLen
-
-	buf[index] = VERSION
-	index++
-
-	if c.compress {
-		buf[index] = 0x01
-	} else {
-		buf[index] = 0
-	}
-	index++
-
-	binary.BigEndian.PutUint16(buf[index:index+2], uint16(channelLen))
-	index += 2
-	copy(buf[index:index+channelLen], []byte(channel))
-	index += channelLen
-
-	copy(buf[index:], auth)
+	buf := conn.AuthPackageEncode(PROTO, VERSION, channel, auth, c.compress)
 	return c.WriteRawPackage(buf, true)
 }
 
@@ -284,205 +251,53 @@ func (c *Ws2) ReadAuthInfo() (proto string, version uint8, channel string, auth
 			return
 		}
 	}()
-	// 由于这里返回的数据都不需要回收,故不做判断处理
-	msg, _, err := c.ReadRawPackage(c.cf.ReadWait)
-	// err = c.conn.SetReadDeadline(time.Now().Add(time.Millisecond * time.Duration(c.cf.ReadWait)))
-	// if err != nil {
-	// 	return
-	// }
-	// _, msg, err := c.conn.ReadMessage()
+	msg, recycle, err := c.ReadRawPackage(c.cf.ReadWait)
 	if err != nil {
 		return
 	}
-	msgLen := len(msg)
-	if msgLen < 9 {
-		err = errors.New("wrong message length")
-		return
-	}
-	// 将读出来的数据进行解密
-	if c.cipher != nil {
-		c.cipher.Decrypt(msg, msg)
-	}
-	index := 0
-	id := binary.BigEndian.Uint16(msg[index : index+2])
-	if id != config.ID_AUTH {
-		err = fmt.Errorf("wrong message id: %d", id)
-		return
-	}
-	index += 2
-
-	protoLen := int(msg[index])
-	if protoLen < 2 {
-		err = errors.New("wrong proto length")
+	var compress bool
+	proto, version, compress, channel, auth, err = conn.AuthPackageDecode(msg, recycle)
+	if err != nil {
 		return
 	}
-	index++
-	proto = string(msg[index : index+protoLen])
 	if proto != PROTO {
 		err = fmt.Errorf("wrong proto: %s", proto)
 		return
 	}
-	index += protoLen
-
-	version = msg[index]
 	if version != VERSION {
 		err = fmt.Errorf("require version %d, get version: %d", VERSION, version)
 		return
 	}
-	index++
-
-	c.compress = (msg[index] & 0x01) != 0
-	index++
-
-	channelLen := int(binary.BigEndian.Uint16(msg[index : index+2]))
-	if channelLen < 2 {
-		err = errors.New("wrong channel length")
-		return
-	}
-	index += 2
-	channel = string(msg[index : index+channelLen])
-	index += channelLen
-
-	auth = msg[index:]
+	c.compress = compress
 	return
 }
 
 // 发送请求数据包到网络
 func (c *Ws2) WriteRequest(id uint16, cmd string, data []byte) error {
-	// 为了区分请求还是响应包,命令字符串不能超过127个字节,如果超过则报错
-	cmdLen := len(cmd)
-	if cmdLen > 0x7F {
-		return errors.New("length of command more than 0x7F")
-	}
-	dlen := len(data)
-	if c.compress && dlen > 0 {
-		compressedData, ok, _ := util.CompressData(data)
-		ddlen := 2 + 1 + cmdLen + 1 + len(compressedData)
-		// buf := make([]byte, ddlen) // 申请内存
-		buf := pool.Get(ddlen)
-		index := 0
-		binary.BigEndian.PutUint16(buf[index:index+2], id)
-		index += 2
-
-		buf[index] = byte(cmdLen)
-		index++
-		copy(buf[index:], cmd)
-		index += cmdLen
-
-		if ok {
-			buf[index] = 0x01
-			if c.cf.PrintMsg {
-				log.Println("[CompressData]", len(data), "->", len(compressedData))
-			}
-		} else {
-			buf[index] = 0
-		}
-		index++
-
-		copy(buf[index:], compressedData)
-		return c.WriteRawPackage(buf, true)
-	} else {
-		ddlen := 2 + 1 + cmdLen + dlen
-		buf := pool.Get(ddlen)
-		binary.BigEndian.PutUint16(buf[0:2], id)
-		buf[2] = byte(cmdLen)
-		copy(buf[3:], cmd)
-		copy(buf[3+cmdLen:], data)
-		return c.WriteRawPackage(buf, true)
-	}
+	buf := conn.RequestPackageEncode(id, cmd, data, c.compress, c.cf)
+	return c.WriteRawPackage(buf, true)
 }
 
 // 发送响应数据包到网络
 // 网络格式:[id, stateCode, data]
 func (c *Ws2) WriteResponse(id uint16, state uint8, data []byte) error {
-	dlen := len(data)
-	if c.compress && dlen > 0 {
-		compressedData, ok, _ := util.CompressData(data)
-		ddlen := 2 + 1 + 1 + len(compressedData)
-		buf := pool.Get(ddlen)
-		binary.BigEndian.PutUint16(buf[0:2], id)
-		buf[2] = state | 0x80
-		if ok {
-			buf[3] = 0x01
-			if c.cf.PrintMsg {
-				log.Println("[CompressData]", len(data), "->", len(compressedData))
-			}
-		} else {
-			buf[3] = 0
-		}
-		copy(buf[4:], compressedData)
-		return c.WriteRawPackage(buf, true)
-	} else {
-		ddlen := 2 + 1 + dlen
-		buf := pool.Get(ddlen)
-		binary.BigEndian.PutUint16(buf[0:2], id)
-		buf[2] = state | 0x80
-		copy(buf[3:], data)
-		return c.WriteRawPackage(buf, true)
-	}
+	buf := conn.ResponsePackageEncode(id, state, data, c.compress, c.cf)
+	return c.WriteRawPackage(buf, true)
 }
 
 // 发送ping包
 func (c *Ws2) WritePing(id uint16) error {
-	buf := pool.Get(2)
-	binary.BigEndian.PutUint16(buf[0:2], id)
+	buf := conn.PingPackageEncode(id)
 	return c.WriteRawPackage(buf, true)
 }
 
 // 获取信息
 func (c *Ws2) ReadMessage(deadline int) (msgType conn.MsgType, id uint16, cmd string, state uint8, data []byte, err error) {
-	msg, _, err := c.ReadRawPackage(deadline)
-	// err = c.conn.SetReadDeadline(time.Now().Add(time.Millisecond * time.Duration(deadline)))
-	// if err != nil {
-	// 	return
-	// }
-	// _, msg, err := c.conn.ReadMessage()
+	msg, recycle, err := c.ReadRawPackage(deadline)
 	if err != nil {
 		return
 	}
-	msgLen := len(msg)
-	if msgLen < 2 {
-		err = errors.New("message length less than 2")
-		return
-	}
-	// 将读出来的数据进行解密
-	if c.cipher != nil {
-		c.cipher.Decrypt(msg, msg)
-	}
-	id = binary.BigEndian.Uint16(msg[0:2])
-	// ping信息
-	if msgLen == 2 {
-		msgType = conn.PingMsg
-		return
-	}
-
-	if id > config.ID_MAX {
-		err = fmt.Errorf("wrong message id: %d", id)
-		return
-	}
-
-	cmdx := msg[2]
-	if (cmdx & 0x80) == 0 {
-		// 请求包
-		msgType = conn.RequestMsg
-		cmdLen := int(cmdx)
-		cmd = string(msg[3 : cmdLen+3])
-		data = msg[cmdLen+3:]
-	} else {
-		// 响应数据包
-		msgType = conn.ResponseMsg
-		state = cmdx & 0x7F
-		data = msg[3:]
-	}
-	dataLen := len(data)
-	if c.compress && dataLen > 1 {
-		var ok bool
-		data, ok, err = util.UncompressData(data)
-		if ok && c.cf.PrintMsg {
-			log.Println("[UncompressData]", dataLen, "->", len(data))
-		}
-	}
-	return
+	return conn.PackageDecode(msg, recycle, c.compress, c.cf)
 }
 
 // 获取远程的地址