Ejemplo n.º 1
0
/*
 客户端退出处理方法
*/
func (this *Server) quitHandler(client *common.Client) {
	if client != nil {
		// 通知在线的好友,我离线了
		if client.Login != nil {
			// 判断要求改变的状态和当前该用户的状态是否一致
			model.DeleteConnByKey(client.Key)
			count, _ := model.CountConnByUserId(client.Login.UserId)
			// 如果没有这用户的连接,同时更新用户状态为离线
			if count == 0 {
				model.UpdateUserStatus(client.Login.UserId, "0")
			}
			keys, err := model.GetBuddiesKeyById(client.Login.UserId)
			if err == nil {
				for i := 0; i < len(keys); i++ {
					//给对应的连接推送好友状态变化的通知
					data := make(map[string]string)
					data["id"] = client.Login.UserId
					data["state"] = "0"
					if this.clients[keys[i]] != nil {
						this.clients[keys[i]].PutOut(common.NewIMResponseData(util.SetData("user", data), common.PUSH_STATUS_CHANGE))
					}
				}
			}
		}

		// 调用客户端关闭方法
		client.Close()
		delete(this.clients, client.Key)

		//		log.Printf("客户端退出: %s online:%d", client.Key, len(ClientMaps))
	}
}
Ejemplo n.º 2
0
/*
 接收消息处理方法
*/
func (this *Server) receivedHandler(request common.IMRequest) {
	//	log.Println("开始读取数据")
	//	log.Println("读取的数据为", request)

	// 获取请求的客户端
	client := request.Client
	// 获取请求数据
	reqData := request.Data
	//	log.Printf("客户端:[%s]发送命令:[%s]消息内容:[%s]", client.Key, request.Command, request.Data)

	// 未登录业务处理部分
	switch request.Command {
	case common.GET_CONN:
		token := reqData["user"]["token"]
		if token == "" {
			client.PutOut(common.NewIMResponseSimple(301, "用户令牌不能为空!", common.GET_CONN_RETURN))
			return
		}
		// 校验用户是否登录,把Login数据放在client当中
		login, err := model.GetLoginByToken(token)
		if err != nil {
			client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.GET_CONN_RETURN))
			return
		}
		client.Login = login
		//		log.Printf("登录比较:token=%s Login=%s", token, client.Login)
		if !strings.EqualFold(client.Login.Token, token) {
			client.PutOut(common.NewIMResponseSimple(302, "该用户令牌无效!", common.GET_CONN_RETURN))
			return
		}
		if client.Login.Id != "" {
			// 更新在线状态,如果现在已经是在线,然后再设置在线,影响行还是为0
			_, err := model.UpdateUserStatus(client.Login.UserId, "1")
			if err != nil {
				client.PutOut(common.NewIMResponseSimple(304, "设置用户状态失败!", common.GET_CONN_RETURN))
				return
			}
			// 创建或者更新连接信息 这个error不能handler,当没有数据时会为 sql: no rows in result set
			conn, _ := model.GetConnByToken(token)
			if conn != nil {
				_, err := model.UpdateConnByToken(client.Key, client.Login.UserId, token)
				if err != nil {
					client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.GET_CONN_RETURN))
					return
				}
			} else {
				_, err := model.AddConn(client.Key, client.Login.UserId, token)
				if err != nil {
					client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.GET_CONN_RETURN))
					return
				}
			}
			data := make(map[string]interface{})
			data["status"] = 1
			client.PutOut(common.NewIMResponseData(util.SetData("conn", data), common.GET_CONN_RETURN))
			// 通知在线的好友,我上线了
			keys, err := model.GetBuddiesKeyById(client.Login.UserId)
			if err != nil {
				client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.SEND_STATUS_CHANGE))
				return
			}
			for i := 0; i < len(keys); i++ {
				//给对应的连接推送好友状态变化的通知
				data := make(map[string]string)
				data["id"] = client.Login.UserId
				data["state"] = "1"
				if this.clients[keys[i]] != nil {
					this.clients[keys[i]].PutOut(common.NewIMResponseData(util.SetData("user", data), common.PUSH_STATUS_CHANGE))
				}
			}
			return
		} else {
			client.PutOut(common.NewIMResponseSimple(303, "用户未登录!", common.GET_CONN_RETURN))
			return
		}
	}
	// 校验连接是已经授权
	if client.Login == nil {
		client.PutOut(common.NewIMResponseSimple(401, "用户未登录!", common.UNAUTHORIZED))
		return
	}
	// 已经登录业务逻辑部分
	switch request.Command {
	case common.GET_BUDDY_LIST:
		// 获取好友分组列表
		categories, err := model.GetCategoriesByUserId(client.Login.UserId)
		if err != nil {
			client.PutOut(common.NewIMResponseSimple(301, "获取好友分类错误!", common.GET_BUDDY_LIST_RETURN))
			return
		}
		categories, err = model.GetBuddiesByCategories(categories)
		if err != nil {
			client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.GET_BUDDY_LIST_RETURN))
			return
		}
		client.PutOut(common.NewIMResponseData(util.SetData("categories", categories), common.GET_BUDDY_LIST_RETURN))
		//初始化好友列表之后 检查该用户有没有未读的好友请求 并推送给用户
		buddyRequests, err := model.GetBuddyRequestsByReceiver(client.Login.UserId)
		if err != nil {
			client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.GET_BUDDY_LIST_RETURN))
		}
		if len(buddyRequests) > 0 {
			for _, buddyRequest := range buddyRequests {
				user, _ := model.GetUserById(buddyRequest.Sender)
				data := make(map[string]interface{})
				data["id"] = user.Id
				data["nick"] = user.Nick
				data["status"] = user.Status
				data["sign"] = user.Sign
				data["avatar"] = user.Avatar
				data["buddyRequestId"] = buddyRequest.Id
				client.PutOut(common.NewIMResponseData(util.SetData("user", data), common.PUSH_BUDDY_REQUEST))
			}
		}
	case common.CREATE_SESSION:
		// 创建会话  //{"command":"CREATE_SESSION","data":{"session":{"sender":"xxx","receiver":"xxx","token":"xxxx"}}}
		sender := reqData["session"]["sender"]
		receiver := reqData["session"]["receiver"]

		if sender == "" {
			client.PutOut(common.NewIMResponseSimple(301, "发送者不能为空!", common.CREATE_SESSION_RETURN))
			return
		}
		if receiver == "" {
			client.PutOut(common.NewIMResponseSimple(302, "接收者不能为空!", common.CREATE_SESSION_RETURN))
			return
		}
		conversationId := model.GetSession(sender, receiver).Id
		if conversationId == "" {
			conversationId = model.AddSession(sender, receiver)
		}
		if conversationId == "" {
			client.PutOut(common.NewIMResponseSimple(303, "创建会话失败", common.GET_CONN_RETURN))
			return
		} else {
			data := make(map[string]string)
			data["ticket"] = conversationId
			data["receiver"] = receiver
			client.PutOut(common.NewIMResponseData(util.SetData("session", data), common.CREATE_SESSION_RETURN))
		}

	case common.SEND_MSG:
		ticket := reqData["message"]["ticket"]
		content := reqData["message"]["content"]

		if ticket == "" {
			client.PutOut(common.NewIMResponseSimple(301, "Ticket不能为空!", common.SEND_MSG_RETURN))
			return
		}
		if content == "" {
			client.PutOut(common.NewIMResponseSimple(302, "消息内容不能为空!", common.SEND_MSG_RETURN))
			return
		}
		conversion, err := model.GetSessionById(ticket)
		if err != nil {
			client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.SEND_MSG_RETURN))
			return
		}
		if conversion.Id != "" {
			isSent := false
			keys, err := model.GetReceiverKeyByTicket(ticket)
			if err != nil {
				client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.SEND_MSG_RETURN))
				return
			}
			for _, key := range keys {
				if this.clients[key] == nil {
					// client.PutOut(common.NewIMResponseSimple(402, "对方还未登录!", common.SEND_MSG_RETURN))
					continue
				}
				// 把消息转发给接收者
				data := make(map[string]string)
				data["sender"] = client.Login.UserId
				data["ticket"] = ticket
				data["content"] = content
				log.Println("开始转发给:", key)
				this.clients[key].PutOut(common.NewIMResponseData(util.SetData("message", data), common.PUSH_MSG))
				isSent = true
			}
			if !isSent {
				client.PutOut(common.NewIMResponseSimple(304, "对方不在线!", common.GET_CONN_RETURN))
				return
			}
		} else {
			client.PutOut(common.NewIMResponseSimple(303, "会话已关闭!", common.SEND_MSG_RETURN))
			return
		}

	case common.SEND_STATUS_CHANGE:
		status := reqData["user"]["status"]
		if status == "" {
			client.PutOut(common.NewIMResponseSimple(301, "状态不能为空!", common.SEND_STATUS_CHANGE))
			return
		}
		user, err := model.GetUserByToken(client.Login.Token)
		if err != nil {
			client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.SEND_STATUS_CHANGE))
			return
		}
		//判断用户的合法性
		if user.Id == "" {
			//判断要求改变的状态和当前该用户的状态是否一致
			if strings.EqualFold(user.Status, status) {
				//FIXME 此处不做如果状态是离线就删除用户连接的操作,状态改变认为是客户端手动操作或者网络异常
				_, err := model.UpdateUserStatus(user.Id, status)
				if err != nil {
					client.PutOut(common.NewIMResponseSimple(304, err.Error(), common.SEND_STATUS_CHANGE))
					return
				}
				keys, err := model.GetBuddiesKeyById(user.Id)
				if err != nil {
					client.PutOut(common.NewIMResponseSimple(300, err.Error(), common.SEND_STATUS_CHANGE))
					return
				}
				for i := 0; i < len(keys); i++ {
					//给对应的连接推送好友状态变化的通知
					data := make(map[string]string)
					data["id"] = user.Id
					data["state"] = reqData["user"]["status"]
					this.clients[keys[i]].PutOut(common.NewIMResponseData(util.SetData("user", data), common.PUSH_STATUS_CHANGE))
				}
			} else {
				client.PutOut(common.NewIMResponseSimple(303, "请退出重新登录!", common.SEND_STATUS_CHANGE))
				return
			}

		} else {
			client.PutOut(common.NewIMResponseSimple(302, "Token不合法!", common.SEND_STATUS_CHANGE))
			return
		}
	case common.LOGOUT_REQUEST:
		client.Quiting()
	case common.SEND_BUDDY_REQUEST:
		receiver := reqData["buddyRequest"]["receiver"]
		//判断接收者是不是在线
		user, _ := model.GetUserById(receiver)
		if user == nil || user.Status == "0" { //不在线 记录到好友请求表中
			id, _ := model.AddBuddyRequest(reqData["buddyRequest"]["sender"], reqData["buddyRequest"]["senderCateId"], receiver)
			if id != nil {

			}
		} else { //在线直接推送给接收者
			conn, _ := model.GetConnByUserId(receiver)
			data := make(map[string]string)
			data["sender"] = reqData["buddyRequest"]["sender"]
			data["senderCateId"] = reqData["buddyRequest"]["senderCateId"]
			data["receiver"] = reqData["buddyRequest"]["receiver"]
			this.clients[conn.Key].PutOut(common.NewIMResponseData(util.SetData("buddyRequest", data), common.PUSH_BUDDY_REQUEST))
		}

	}
}