Example #1
0
// 处理客户端之间的消息转发
func HandleC2CTextChat(conn *net.TCPConn, recPacket *packet.Packet) {
	// read
	readMsg := &pb.PbC2CTextChat{}
	packet.Unpack(recPacket, readMsg)

	from_uuid := ConnMapUuid.Get(conn).(string)
	to_uuid := readMsg.GetToUuid()
	txt_msg := readMsg.GetTextMsg()
	timestamp := readMsg.GetTimestamp()

	// 验证发送者的真实性以及发送对象是否存,若消息伪造,则断开该连接
	if readMsg.GetFromUuid() != from_uuid || !dao.UuidCheckExist(to_uuid) {
		CloseConn(conn)
		return
	}

	// write
	writeMsg := &pb.PbC2CTextChat{
		FromUuid:  proto.String(from_uuid),
		ToUuid:    proto.String(to_uuid),
		TextMsg:   proto.String(txt_msg),
		Timestamp: proto.Int64(timestamp),
	}
	pac, err := packet.Pack(packet.PK_C2CTextChat, writeMsg)
	if err != nil {
		log.Printf("%v\r\n", err)
		return
	}

	// 若 to_uuid 在线,则转发该消息,发送失败 或者 to_uuid不在线 则保存为离线消息
	if dao.UuidCheckOnline(to_uuid) {
		// fmt.Println("在线消息转发")
		to_conn := UuidMapConn.Get(to_uuid).(*net.TCPConn)
		if SendByteStream(to_conn, pac.GetBytes()) != nil {
			// fmt.Println("发送失败转离线消息保存")
			dao.OfflineMsgAddMsg(to_uuid, string(pac.GetBytes()))
			report.AddCount(report.OfflineMsg, 1)
		} else {
			report.AddCount(report.OnlineMsg, 1)
		}
	} else {
		// fmt.Println("不在线转离线消息保存")
		dao.OfflineMsgAddMsg(to_uuid, string(pac.GetBytes()))
		report.AddCount(report.OfflineMsg, 1)
	}
}
Example #2
0
// 处理登陆
func HandleClientLogin(conn *net.TCPConn, recPacket *packet.Packet) {
	// read
	readMsg := &pb.PbClientLogin{}
	packet.Unpack(recPacket, readMsg)

	uuid := readMsg.GetUuid()

	// 检测uuid合法性
	if dao.UuidCheckExist(uuid) {
		// 如果已经在线则关闭以前的conn
		if dao.UuidCheckOnline(uuid) {
			co := UuidMapConn.Get(uuid)
			if co != nil {
				CloseConn(co.(*net.TCPConn))
			}
		}
		// 上线conn
		InitConn(conn, uuid)
	} else {
		CloseConn(conn)
	}

	// fmt.Println("uuid:", readMsg.GetUuid())
	// fmt.Println("version:", readMsg.GetVersion())
	// fmt.Println("timestamp:", convert.TimestampToTimeString(readMsg.GetTimestamp()))

	// write
	writeMsg := &pb.PbServerAcceptLogin{
		Login:     proto.Bool(true),
		TipsMsg:   proto.String("登陆成功"),
		Timestamp: proto.Int64(time.Now().Unix()),
	}
	SendPbData(conn, packet.PK_ServerAcceptLogin, writeMsg)

	// 检查是否有该uuid的离线消息存在,若有,则发送其离线消息
	if dao.OfflineMsgCheck(uuid) {
		// 这里比较复杂,后续再优化(可以多个离线消息一起发送)
		// 得到所有离线消息的id
		msgids := dao.OfflineMsgGetIds(uuid)
		// fmt.Println(uuid, "有离线消息,数量为:", len(msgids))
		var (
			k   int
			err error
		)
		for k, _ = range msgids {
			if err = SendByteStream(conn, []byte(dao.IdMsgGetMsgFromId(msgids[k]))); err != nil {
				break
			}
			// fmt.Println("正在发送离线消息", k, err, dao.IdMsgGetMsgFromId(msgids[k]))
		}

		if err != nil {
			if k != 0 {
				dao.OfflineMsgDeleteIds(uuid, msgids[k-1])
			}
		} else {
			dao.OfflineMsgDeleteIds(uuid, msgids[k])
		}
	} else {
		// fmt.Println("没有离线消息")
	}

}