// 1. user login first // 2. old user not in meeting and online --> send msg to he and replace he // 3. old user not in meeting and offline --> replace he and online // 4. old user in meeting and is not admin and online --> send msg to // he and replace he and send meeting info to new user and online and // into meeting and tell other user // 5. old user in meeting and is admin and online --> same 4 // 6. old user in meeting and is not admin and offline --> 4 (don't // send msg to he) // 7. old user in meeting and is admin and offline --> same 4(dont't // sned msg to he) int Msm::login(string id, string name, int sockfd) { Member *m = new Member(id, name); Meeting *meeting = NULL; if (have_member(id)) { Member *m_old = get_member(id); m->set_volum(m_old->get_volum()); m->set_status(m_old->get_status()); // close old sockfd int old_fd; old_fd = m_old->get_sockfd(); // send msg to old user if (m_old->is_online()) { MsmReqMsg msg(id, "close", "duplicate user"); msg.send_msg(old_fd); } #if 1 if (old_fd != -1 && old_fd != sockfd) { if (epoll_ctl(epollfd, EPOLL_CTL_DEL, old_fd, &ev) == -1) { LOG(LOG_ERROR, "epoll_ctl del %d failed: %s", old_fd, strerror(errno)); return errno; } close(old_fd); m_old->set_sockfd(-1); LOG(LOG_INFO, "close sockfd: %d", old_fd); } #endif // delete old user in meeting meeting = m_old->get_meeting(); if (meeting != NULL) { meeting->del_member(m_old); } // delete struct old user logout(m_old->get_id()); } register_member(m); m->set_sockfd(sockfd); m->set_online(); if (meeting != NULL) { /// TODO: send meeting info to user meeting->add_member(m); } LOG(LOG_DEBUG, "%s login", id.c_str()); return 0; }
int Msm::epoll_pollin(int fd) { LOG(LOG_DEBUG, "socket: %d EPOLLIN event.", fd); char buf[1024]; memset(buf, 0, sizeof(buf)); // int rc = recv(events[n].data.fd, buf, sizeof(buf)-1, 0); struct msghdr msghdr; struct iovec iov; memset(&msghdr, 0, sizeof(msghdr)); iov.iov_base = buf; iov.iov_len = sizeof(buf); msghdr.msg_iov = &iov; msghdr.msg_iovlen = 1; int rc = recvmsg(fd, &msghdr, 0); if (rc == -1) { LOG(LOG_ERROR, "socket: %d recvmsg failed: %s", fd, strerror(errno)); return -1; } else if (rc == 0) { LOG(LOG_ERROR, "socket: %d recvmsg 0, socket is closed by user.", fd); if (get_member_byfd(fd) != NULL) { logout(get_member_byfd(fd)->get_id()); } return -1; } LOG(LOG_DEBUG, "socket: %d recvmsg:\n%s", fd, buf); Json::Value root; Json::Reader reader; if (reader.parse(buf, root, false) == false) { LOG(LOG_DEBUG, "json parse failed."); return -1; } if (epoll_closefd_before(root["action"].asString(), fd, root["user_id"].asString()) < 0) return -1; msm_msg_t msm_msg; msm_msg.sockfd = fd; msm_msg.root = root; msm_msg.msm = this; actions_handle.find(root["action"].asString())->second(msm_msg); #if 0 if (root["action"] == "login") { login(root["user_id"].asString(), root["user_name"].asString(), fd); // send_test(root["from"].asString()); } else if (root["action"] == "logout") { logout(root["user_id"].asString()); } else if (root["action"] == "heartbeat") { } else if (root["action"] == "askmeeting") { create_meeting(root["meeting_id"].asString(), root["meeting_name"].asString()); get_meeting(root["meeting_id"].asString())->add_member(get_member(root["user_id"].asString())); get_meeting(root["meeting_id"].asString())->set_admin(root["user_id"].asString()); } else if (root["action"] == "adduser") { if (get_meeting(root["meeting_id"].asString()) != NULL) { if (get_member(root["users"].asString()) == NULL) { Member *m = new Member(root["users"].asString(), "Unkown"); m->set_offline(); register_member(m); } get_meeting(root["meeting_id"].asString())->add_member(get_member(root["users"].asString())); } } else if (root["action"] == "leavemeeting") { Meeting *meeting = get_meeting(root["meeting_id"].asString()); if (meeting != NULL) { Member *m = get_member(root["user_id"].asString()); if (m->get_id() != meeting->get_admin()) { meeting->del_member(m); } else { destroy_meeting(meeting->get_id()); } } } else { } #endif epoll_closefd_after(root["action"].asString(), fd, root["user_id"].asString()); dump_members(); dump_meetings(); return 0; }