コード例 #1
0
ファイル: session.go プロジェクト: HYQMartin/mybeeim
func CreateSession(conns net.Conn, imDB imdatabase.ImDb) *Session {
	//sqlerr := make(chan (error))             //当数据库读写出错,则返回nil,ErrorMysql
	ClientSession := setSession(conns)       //初始化session
	publicPacket := MakePacket(PublicCMD, 0) //type=0的包 也就是发公钥的包
	ClientSession.outgoing <- *publicPacket  //首先把RSA的Public Key 发过去
	for {                                    //等待一定时间 回馈包,里面要求 username,appkey,aeskey。时间超过,或者里面内容不符合直接关掉conn
		select {
		case requestPacket := <-ClientSession.incoming:
			{ //对进来的包进行检验
				//isloged, userUid := receiveLoginPacket(ClientSession, requestPacket)
				if requestPacket.GetType() != 1 {
					*returnCMD.Sender = 0
					*returnCMD.Receiver = 1
					*returnCMD.Message.Data = "1:Please login first!"
					returnPacket := MakePacket(returnCMD, 3)
					ClientSession.outgoing <- *returnPacket
					//ImServerLog("A user didn't use a type 1 packet to login.")
					break
				}
				//if requestPacket.GetType() == 1 { //mean that this is a requestPacket
				requestCMD, err := GetCommand(&requestPacket) //Type=1的包,包含uid+APPKEY+AESKEY
				if err != nil {
					//回馈??
					ImServerLog("RequestCMD  get login command error ", err) ///////////////////////////////////////////
					break
				}
				//验证名字是否登陆了,验证APPKEY是否正确,如果都正确,纪录AESKEY,返回AESKEY加密的回馈包:uid
				appKey := requestCMD.Message.GetPassword()
				userUid := requestCMD.GetSender()
				token := requestCMD.Message.GetName()
				random := requestCMD.Message.GetRandom()
				aesKey := requestCMD.Message.GetData()
				//先看有没token
				_, fla := UserTable[userUid]
				if fla == false {
					//fmt.Println("*****************************用户不存在")
					//用户未先登录业务服务器
					ClientSession.packetReader.AESKEY = []byte(aesKey)
					ClientSession.packetWriter.AESKEY = []byte(aesKey)
					*returnCMD.Sender = 0
					*returnCMD.Receiver = userUid
					*returnCMD.Message.Random = random
					*returnCMD.Message.Data = "1:User don't login successfully!"
					notokenreturnPacket := MakePacket(returnCMD, 3)
					ClientSession.outgoing <- *notokenreturnPacket
					break
				}
				var userToken string
				userToken = UserTable[userUid].AToken
				if appKey != APPKEY || token != userToken {
					*returnCMD.Sender = 0
					*returnCMD.Receiver = userUid
					*returnCMD.Message.Random = random
					*returnCMD.Message.Data = "1:Wrong AppKey or Token."
					wrongkeyreturnPacket := MakePacket(returnCMD, 3)
					ClientSession.outgoing <- *wrongkeyreturnPacket
					break
				}
				//if appKey == APPKEY && token == userToken { //have the same appkey and online and have the same token
				//从这里开始可以对imDB操作
				ClientSession.packetReader.AESKEY = []byte(aesKey)
				ClientSession.packetWriter.AESKEY = []byte(aesKey)
				ClientSession.uid = userUid
				//如果存在旧的session tcp 则先关掉旧的,释放tcp资源
				oldSession, flags := SessionTable[userUid]
				if flags == true {
					*returnCMD.Sender = 0
					*returnCMD.Receiver = userUid
					*returnCMD.Message.Random = random
					*returnCMD.Message.Data = "1:Old session is replacing"
					placingreturnPacket := MakePacket(returnCMD, 3)
					oldSession.outgoing <- *placingreturnPacket
					SessionTable[userUid].quit()
					ImServerLog("User: "******" has logined before. Quit the earlier session.") //////////////////////////////////////////////
				}
				SessionTable[userUid] = ClientSession
				UserTable[userUid] = Token{UserTable[userUid].AToken, 1}
				*returnCMD.Sender = 0
				*returnCMD.Receiver = userUid
				*returnCMD.Message.Random = random
				*returnCMD.Message.Data = "1:Connect successfully."
				successreturnPacket := MakePacket(returnCMD, 3)
				ClientSession.outgoing <- *successreturnPacket

				//*********************************************************************************
				//goThroughOutLineMessage(userUid, imDB)
				outLineMessageTableFromSql, err := imDB.Db.Query("select type,packet,timestamp from outlinemessage where receiver_id=? order by timestamp asc", userUid)
				if err != nil {
					DatabaseLog("database error in prepare reading outlinemesssage:" + err.Error())
				}
				defer outLineMessageTableFromSql.Close()
				if err == nil {
					//DatabaseLog("select from outlinemessage receiver_id = ", userUid)
					//在离线表找到数据
					var outLineMsgType uint32
					var outLineMsgePacket []byte
					var outLineMsgTime string
					//切片存储所有扫描出来的离线包信息
					var allOutLineMsgType []uint32
					var allOutLineMsgePacket []string //string类型
					//var allOutLineMsgTime []string
					allOutLineMsgType = make([]uint32, 0, MaxOutLineMsg)
					allOutLineMsgePacket = make([]string, 0, MaxOutLineMsg)
					//allOutLineMsgTime = make([]string, 0, MaxOutLineMsg)

					for outLineMessageTableFromSql.Next() {
						err := outLineMessageTableFromSql.Scan(&outLineMsgType, &outLineMsgePacket, &outLineMsgTime)
						if err != nil {
							DatabaseLog("database error in reading outlinemesssage:" + err.Error())
							continue
						}
						allOutLineMsgType = append(allOutLineMsgType, outLineMsgType)
						allOutLineMsgePacket = append(allOutLineMsgePacket, string(outLineMsgePacket))
					}
					outLineMessageTableFromSql.Close()
					for i, _ := range allOutLineMsgType {
						var outLinePacket Packet
						outLinePacket.SetType(allOutLineMsgType[i])
						outLinePacket.SetData([]byte(allOutLineMsgePacket[i]))
						outLineCMD, err := GetCommand(&outLinePacket)
						if err != nil {
							ImServerLog("Outlinemessage GetCommand err : ", err)
							continue
						}
						*outLineCMD.Message.Random = GenRandom()
						outPacket := MakePacket(outLineCMD, outLinePacket.GetType())
						_, fl := SessionTable[userUid]
						if fl {
							SessionTable[userUid].outgoing <- *outPacket
						}
					}
					err = imDB.DeleteDbTable("delete from outlinemessage where receiver_id=?", userUid)
					if err != nil {
						DatabaseLog("Delete from outlinemessage error", err)
					}
				}
				//ImBusinessLog("Delete outlinemessage receiver_id = ", userUid)
				//return true

				//if isGetOutLineMessage == false {
				//	SessionTable[userUid].quit()
				//	return nil, ErrorMysql
				//} else {
				SessionTable[userUid] = ClientSession
				go receiveMessagePacket(userUid, imDB)
				return ClientSession
				//}

			}
			//case <-time.After(time.Second * MaxDelayTime):
			//{
			//	_, flag := SessionTable[userUid]
			//	if flag {
			//		SessionTable[userUid].quit()
			//		ImServerLog("Client didn't login after receiving rsa key in MaxDelayTime.") ///////////////////////////////////////////////////
			//	}
			//		return nil, nil
			//}
			//case caseerr := <-sqlerr:
			//	{
			//		if caseerr == ErrorMysql {
			//			return nil, ErrorMysql
			//		}
			//	}
		}
	}
	return nil
}