Beispiel #1
0
//写入文件
func (s *server) dump(db *bolt.DB, changes map[uint64]bool) {
	//写入已经更改的id
	for k := range changes {
		//读取message
		ep := s.read_ep(k)
		if ep == nil {
			log.Errorf("canot find endpoint %v", k)
			continue
		}

		//序列化数据
		bin, err := msgpack.Marshal(ep.Read())
		if err != nil {
			log.Critical("canot marshal:", err)
			continue
		}

		//更新表
		db.Update(func(tx *bolt.Tx) error {
			//拿到表句柄
			b := tx.Bucket([]byte(BOLTDB_BUCKET))
			//存入数据, k-v形式
			err := b.Put([]byte(fmt.Sprint(k)), bin)
			return err
		})
	}
}
Beispiel #2
0
//订阅消息, 通过Chat_Id
func (s *server) Subscribe(p *Chat_Id, stream ChatService_SubscribeServer) error {
	die := make(chan bool)
	//包装消息
	f := pubsub.NewWrap(func(msg *Chat_Message) {
		//发送message
		if err := stream.Send(msg); err != nil {
			// 出错时, 取消订阅
			close(die)
		}
	})

	log.Tracef("new subscriber: %p", f)

	//读取消息盒子
	ep := s.read_ep(p.Id)
	if ep == nil {
		log.Errorf("canot find endpoint %v", p)
		return ERROR_NOT_EXISTS
	}

	//订阅消息
	ep.ps.Sub(f)
	defer func() {
		ep.ps.Leave(f)
	}()

	<-die
	return nil
}
Beispiel #3
0
func PrintPanicStack(extras ...interface{}) {
	if x := recover(); x != nil {
		log.Error(x)
		i := 0
		funcName, file, line, ok := runtime.Caller(i)
		for ok {
			log.Errorf("frame %v:[func:%v,file:%v,line:%v]\n", i, runtime.FuncForPC(funcName).Name(), file, line)
			i++
			funcName, file, line, ok = runtime.Caller(i)
		}

		for k := range extras {
			log.Errorf("EXRAS#%v DATA:%v\n", k, spew.Sdump(extras[k]))
		}
	}
}
Beispiel #4
0
//注册消息通道
func (s *server) Reg(ctx context.Context, p *Chat_Id) (*Chat_Nil, error) {
	s.Lock()
	defer s.Unlock()
	//通过id读取消息盒子
	ep := s.eps[p.Id]
	//判断是否已注册
	if ep != nil {
		log.Errorf("id already exists:%v", p.Id)
		return nil, ERROR_ALREADY_EXISTS
	}

	//一个消息id绑定一个endpoint
	s.eps[p.Id] = NewEndPoint()
	//标记要保存的id
	s.pending <- p.Id
	return OK, nil
}
Beispiel #5
0
//通过Chat_Id读取消息
func (s *server) Read(p *Chat_Id, stream ChatService_ReadServer) error {
	ep := s.read_ep(p.Id)
	if ep == nil {
		log.Errorf("canot find endpoint %v", p)
		return ERROR_NOT_EXISTS
	}

	//如果读到消息
	msgs := ep.Read()
	for k := range msgs {
		//发送消息
		if err := stream.Send(&msgs[k]); err != nil {
			return err
		}
	}
	return nil
}
Beispiel #6
0
// client protocol handle proxy
func proxy_user_request(sess *Session, p []byte) []byte {
	start := time.Now()
	defer utils.PrintPanicStack()
	//解密
	if sess.Flag&SESS_ENCRYPT != 0 {
		//使用2组密钥匙, 增加破解难度
		sess.Decoder.XORKeyStream(p, p)
	}

	//封装成reader
	reader := packet.Reader(p)

	// 读客户端数据包序列号(1,2,3...)
	// 可避免重放攻击-REPLAY-ATTACK
	//数据包的前4个字节存放的是客户端的发包数量
	//客户端每次发包要包含第几次发包信息
	seq_id, err := reader.ReadU32()
	if err != nil {
		log.Error("read client timestamp failed:", err)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 数据包个数验证
	if seq_id != sess.PacketCount {
		//数据包真实长度是,总长度-4个字节的包个数长度-2个字节的协议号长度
		log.Errorf("illegal packet sequeue id:%v should be:%v size:%v", seq_id, sess.PacketCount, len(p)-6)
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	// 读协议号
	b, err := reader.ReadS16()
	if err != nil {
		log.Error("read protocol number failed.")
		sess.Flag |= SESS_KICKED_OUT
		return nil
	}

	//根据协议号段 做服务划分
	var ret []byte
	if b > MAX_PROTO_NUM {
		//去除4字节发包个数,将其余的向前传递
		if err := forward(sess, p[4:]); err != nil {
			log.Errorf("service id:%v execute failed, error:%v", b, err)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	} else {
		if h := client_handler.Handlers[b]; h != nil {
			ret = h(sess, reader)
		} else {
			log.Errorf("service id:%v not bind", b)
			sess.Flag |= SESS_KICKED_OUT
			return nil
		}
	}

	// 统计处理时间
	elasped := time.Now().Sub(start)
	if b != 0 { //排除心跳包日志
		log.Trace("[REQ]", client_handler.RCode[b])
		_statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, client_handler.RCode[b]), elasped)
	}
	return ret
}