| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- 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
- }
|