package model import ( "encoding/binary" "errors" "fmt" "github.com/gorilla/websocket" "rocommon" "rocommon/rpc" _ "rocommon/service" "rocommon/socket" "rocommon/util" _ "roserver/baseserver/model" _ "roserver/baseserver/router" _ "roserver/serverproto" ) const ( MsgIDLen = 2 // uint16 lenMaxLen = 2 //包体大小2个字节 uint16 msgIdLen = 2 //包ID大小2个字节 uint16 msgSeqlen = 4 //发送序列号2个字节大小,用来断线重连 msgFlaglen = 2 //暂定标记,加解密 1表示RSA,2表示AES MsgBodyIdx = 2 + 4 + 2 + 2 //->10 ) type DirectWSMessageTransmitter struct { } //recv直接原始数据传递到后端 / 返回消息给client func (this *DirectWSMessageTransmitter) OnRecvMsg(s rocommon.Session) (msg interface{}, seqId uint32, err error) { conn, ok := s.Raw().(*websocket.Conn) if !ok || conn == nil { util.InfoF("[DirectWSMessageTransmitter] OnRecvMsg err") return nil, 0, nil } //opt := s.Node().(socket.SocketOption) //var opt socket.SocketOption //if s.GetSessionOptFlag() { // opt = s.Node().(socket.SocketOption) //} else { // opt = s.GetSessionOpt().(socket.SocketOption) //} messageType, raw, err1 := conn.ReadMessage() if err1 != nil { err = err1 util.InfoF("[DirectWSMessageTransmitter] OnRecvMsg ReadMessage err=%v", err) return nil, 0, err1 } switch messageType { case websocket.BinaryMessage: var msgId uint16 //var seqId uint32 //包序列号,客户端发送时的序列从1开始 var flagId uint16 //加密方式 var msgData []byte var msgDataLen uint16 if len(raw) < lenMaxLen { return nil, 0, nil } msgDataLen = binary.BigEndian.Uint16(raw) //msgDataLen raw = raw[lenMaxLen:] if msgDataLen >= 0 { //msgIdLen if len(raw) < msgIdLen { return } msgId = binary.BigEndian.Uint16(raw) raw = raw[msgIdLen:] //msgSeqlen if len(raw) < msgSeqlen { return } seqId = binary.BigEndian.Uint32(raw) raw = raw[msgSeqlen:] //msgFlaglen if len(raw) < msgFlaglen { return } flagId = binary.BigEndian.Uint16(raw) msgData = raw[msgFlaglen:] //尝试直接发送到其他后端服务器或者解析 if err == nil { msg, err = FrontendPackageProc(int(msgId), seqId, flagId, msgData, s) } } } return } //send 直接发往客户端的消息 func (this *DirectWSMessageTransmitter) OnSendMsg(s rocommon.Session, msg interface{}) (err error) { conn, ok := s.Raw().(*websocket.Conn) if !ok || conn == nil { util.InfoF("[DirectWSMessageTransmitter] OnRecvMsg err") return nil } //opt := s.Node().(socket.SocketOption) var opt socket.SocketOption if s.GetSessionOptFlag() { opt = s.Node().(socket.SocketOption) } else { opt = s.GetSessionOpt().(socket.SocketOption) } aesKey := s.GetAES() var ( msgData []byte msgId uint16 seqId uint32 msgInfo *rocommon.MessageInfo ) switch m := msg.(type) { case *rocommon.TransmitPacket: msgData = m.MsgData msgId = uint16(m.MsgId) seqId = m.SeqId default: msgData, msgInfo, err = rpc.EncodeMessage(msg) if err != nil { return err } msgId = uint16(msgInfo.ID) } //todo // 注意上层发包不要超过最大值 msgLen := len(msgData) var cryptType uint16 = 0 //握手阶段 if msgId == uint16(rpc.SC_HAND_SHAKE_NTFMsgId) { cryptType = 1 msgData, err = rpc.RSAEncrypt(msgData, rpc.PublicClientKey) if err != nil { return err } msgLen = len(msgData) } else { if len(*aesKey) > 0 && msgId != rpc.SC_PING_ACKMsgId { cryptType = 2 msgData, err = rpc.AESCtrEncrypt(msgData, *aesKey, *aesKey...) //msgData, err = AESCtrEncrypt(msgData, *aesKey) if err != nil { return err } msgLen = len(msgData) } } if msgLen > opt.MaxMsgLen() { err = errors.New(fmt.Sprintf("message too big msgId=%v msglen=%v maxlen=%v", msgId, msgLen, opt.MaxMsgLen())) util.FatalF("SendMessage err=%v", err) err = nil return } //data := make([]byte, lenMaxLen + msgIdLen + msgLen) data := make([]byte, lenMaxLen+msgIdLen+msgSeqlen+msgFlaglen+msgLen) //head + body //lenMaxLen binary.BigEndian.PutUint16(data, uint16(msgLen)) //msgIdLen binary.BigEndian.PutUint16(data[lenMaxLen:], uint16(msgId)) //seq 返回客户端发送的序列号 binary.BigEndian.PutUint32(data[lenMaxLen+msgIdLen:], seqId) //log.Println("sendSeqId:", seqId) //使用的加密方式AES binary.BigEndian.PutUint16(data[lenMaxLen+msgIdLen+msgSeqlen:], cryptType) //body if msgLen > 0 { copy(data[lenMaxLen+msgIdLen+msgSeqlen+msgFlaglen:], msgData) } conn.WriteMessage(websocket.BinaryMessage, data) return }