Exemple #1
0
// 添加好友关系
func handleUserRelationAdd(resp http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		receiver_category_id := req.FormValue("receiver_category_id")
		buddy_request_id := req.FormValue("buddy_request_id")
		buddyrequest, _ := model.GetBuddyRequestById(buddy_request_id)
		if buddyrequest != nil {
			receiver := buddyrequest.Receiver
			sender := buddyrequest.Sender
			sender_category_id := buddyrequest.SenderCategoryId
			//开启事务
			tx, _ := model.Database.Begin()
			//修改好友请求记录中接受人的好友分组ID
			_, err := model.UpdateBuddyRequestReceiverCategoryId(tx, buddy_request_id, receiver_category_id)
			//添加请求人好友关系数据
			_, err = model.AddFriendRelation(tx, receiver, sender_category_id)
			//添加接收人好友关系数据
			_, err = model.AddFriendRelation(tx, sender, receiver_category_id)
			//修改好友请求记录中状态
			_, err = model.UpdateBuddyRequestStatus(tx, buddy_request_id, "1")

			if err != nil {
				tx.Rollback()
				resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
				return
			} else {
				tx.Commit()
				//判断请求者是不是在线 在线就把接受者推送给请求者
				conn, _ := model.GetConnByUserId(sender)
				if conn != nil { //在线
					user, _ := model.GetUserById(receiver)
					data := make(map[string]interface{})
					data["category_id"] = sender_category_id
					data["user"] = user
					ClientMaps[conn.Key].PutOut(common.NewIMResponseData(util.SetData("user", data), common.ADD_BUDDY))
				}
				conn, _ = model.GetConnByUserId(receiver)
				if conn != nil {
					user, _ := model.GetUserById(sender)
					data := make(map[string]interface{})
					data["category_id"] = receiver_category_id
					data["user"] = user
					ClientMaps[conn.Key].PutOut(common.NewIMResponseData(util.SetData("user", data), common.ADD_BUDDY))
				}
				resp.Write(common.NewIMResponseSimple(0, "好友关系建立成功", "").Encode())
				return
			}

		} else {
			resp.Write(common.NewIMResponseSimple(104, "该好友请求不存在", "").Encode())
		}

	} else {
		resp.Write(common.NewIMResponseSimple(404, "Not Found: "+req.Method, "").Encode())
	}
}
Exemple #2
0
/*
 新客户端请求处理方法
*/
func (this *Server) joinHandler(conn net.Conn) {
	//获取UUID作为客户端的key
	key := uuid.New()
	// 创建一个客户端
	client := common.CreateClient(key, conn)
	//给客户端指定key
	this.clients[key] = client
	//	log.Printf("新客户端Key:[%s] online:%d", client.Key, len(ClientMaps))
	// 开启协程不断地接收消息
	go func() {
		for {
			// 客户端读取消息
			msg := <-client.In
			// 消息交给嗅探器 触发对应的处理方法
			this.insniffer <- msg
		}
	}()
	// 开启协程一直等待断开
	go func() {
		for {
			//客户端接收断开请求
			conn := <-client.Quit
			//			log.Printf("客户端:[%s]退出", client.Key)
			//请求交给嗅探器 触发对应的处理方法
			this.quitsniffer <- conn
		}
	}()
	// 返回客户端的唯一标识
	data := make(map[string]interface{})
	data["key"] = key
	client.PutOut(common.NewIMResponseData(util.SetData("conn", data), common.GET_KEY_RETURN))
}
Exemple #3
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))
	}
}
Exemple #4
0
/**
查询请求处理方法
*/
func handleQuery(resp http.ResponseWriter, req *http.Request) {
	nick := req.FormValue("nick")
	users, err := model.QueryUser("nick", "like", nick)
	if err == nil {
		resp.Write(common.NewIMResponseData(util.SetData("users", users), "").Encode())
	}
}
Exemple #5
0
func handleUserCategoryQuery(resp http.ResponseWriter, req *http.Request) {
	id := req.FormValue("id")
	categories, err := model.GetCategoriesByUserId(id)
	if err != nil {
		resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
	} else {
		resp.Write(common.NewIMResponseData(util.SetData("categories", categories), "").Encode())
	}
}
Exemple #6
0
// 系统状态信息
func handleSystem(resp http.ResponseWriter, req *http.Request) {
	mem, _ := mem.VirtualMemory()
	cpuNum, _ := cpu.CPUCounts(true)
	cpuInfo, _ := cpu.CPUPercent(10*time.Microsecond, true)

	data := make(map[string]interface{})
	data["im.conn"] = len(ClientMaps)
	data["mem.total"] = fmt.Sprintf("%vMB", mem.Total/1024/1024)
	data["mem.free"] = fmt.Sprintf("%vMB", mem.Free/1024/1024)
	data["mem.used_percent"] = fmt.Sprintf("%s%%", strconv.FormatFloat(mem.UsedPercent, 'f', 2, 64))
	data["cpu.num"] = cpuNum
	data["cpu.info"] = cpuInfo

	resp.Write(common.NewIMResponseData(data, "").Encode())
}
Exemple #7
0
// 登录主方法
func login(resp http.ResponseWriter, account string, password string, ip string) {
	if account == "" {
		resp.Write(common.NewIMResponseSimple(101, "账号不能为空", "").Encode())
	} else if password == "" {
		resp.Write(common.NewIMResponseSimple(102, "密码不能为空", "").Encode())
	} else {
		num, err := model.CheckAccount(account)
		if err != nil {
			resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
			return
		}
		if num > 0 {
			user, err := model.LoginUser(account, password)
			if err != nil {
				resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
				return
			}
			if !strings.EqualFold(user.Id, "") {
				token := uuid.New()
				if _, err := model.SaveLogin(user.Id, token, ip); err != nil {
					resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
				} else {
					// returnData := make(map[string]string)
					// returnData["id"] = user.Id
					// returnData["nick"] = user.Nick
					// returnData["avatar"] = user.Avatar
					// returnData["status"] = user.Status
					// returnData["token"] = token //token uuid 带 横杠
					// returnData["sign"]=user.Sign
					user.Token = token
					resp.Write(common.NewIMResponseData(util.SetData("user", user), "LOGIN_RETURN").Encode())
				}
			} else {
				resp.Write(common.NewIMResponseSimple(104, "密码错误", "").Encode())
			}
		} else {
			resp.Write(common.NewIMResponseSimple(103, "账号不存在", "").Encode())
		}
	}
}
Exemple #8
0
// 添加好友分类
func handleUserCategoryAdd(resp http.ResponseWriter, req *http.Request) {
	switch req.Method {
	case "GET":
		//获取好友列表
		userId := req.FormValue("user_id")

		categories, err := model.GetCategoriesByUserId(userId)
		if err != nil {
			resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
			return
		}
		categories, err = model.GetBuddiesByCategories(categories)
		if err != nil {
			resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
			return
		}
		resp.Write(common.NewIMResponseData(util.SetData("categories", categories), "").Encode())
	case "POST":
		// 添加好友列表
		userId := req.FormValue("user_id")
		name := req.FormValue("name")

		if userId == "" {
			resp.Write(common.NewIMResponseSimple(101, "用户ID不能为空", "").Encode())
		} else if name == "" {
			resp.Write(common.NewIMResponseSimple(102, "类别名称不能为空", "").Encode())
		} else {
			_, err := model.AddCategory(userId, name)
			if err != nil {
				resp.Write(common.NewIMResponseSimple(103, err.Error(), "").Encode())
			} else {
				resp.Write(common.NewIMResponseSimple(0, "添加分类成功", "").Encode())
			}
		}
	default:
		resp.Write(common.NewIMResponseSimple(404, "Not Found: "+req.Method, "").Encode())

	}
}
Exemple #9
0
func handleUserRelationPush(resp http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		sender_category_id := req.FormValue("sender_category_id")
		sender := req.FormValue("sender")
		receiver := req.FormValue("receiver")
		if sender_category_id == "" {
			resp.Write(common.NewIMResponseSimple(101, "请选择分组", "").Encode())
		} else if sender == "" {
			resp.Write(common.NewIMResponseSimple(102, "请重新登录", "").Encode())
		} else {
			//判断接收人是不是在线 在线直接推送,不在线记录至请求表中
			conn, _ := model.GetConnByUserId(receiver)
			user, _ := model.GetUserById(sender)
			buddyRequestId, err := model.AddBuddyRequest(sender, sender_category_id, receiver)
			if err != nil {
				resp.Write(common.NewIMResponseSimple(100, err.Error(), "").Encode())
			} else {
				if conn != nil { //在线 直接推送 不在线 客户登录时候会激活请求通知
					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"] = buddyRequestId
					ClientMaps[conn.Key].PutOut(common.NewIMResponseData(util.SetData("user", data), common.PUSH_BUDDY_REQUEST))
					resp.Write(common.NewIMResponseSimple(0, "发送好友请求成功", "").Encode())
				}
				resp.Write(common.NewIMResponseSimple(1, "发送好友请求成功", "").Encode())
				return
			}
		}
	} else {
		resp.Write(common.NewIMResponseSimple(404, "Not Found: "+req.Method, "").Encode())
	}
}
Exemple #10
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))
		}

	}
}