客户端间通信功能预览
聊天通信效果信号关联机制
整体的逻辑关系实现
//用户上线显示(包括自身和其他用户)
connect(c,SIGNAL(getUserInfSuccess(int)),this,SLOT(displayUser(int)));
//好友、黑名单、陌生人关系改变
connect(c,SIGNAL(changeRelation(ToolButton*,int,int)),this,SLOT(changeUserRelation(ToolButton*,int,int)));
//处理聊天消息 connect(c,SIGNAL(haveTalkMessage(int,QString)),this,SLOT(haveTalkMessage(int,QString)));
//用户下线处理
connect(c,SIGNAL(userOffline(int)),this,SLOT(userOffline(int)));
//下线成功后界面处理
connect(c,SIGNAL(OfflineSuccess()),this,SLOT(OfflineSuccess()));
各部分具体实现:
1、用户信息显示
新用户上线后,显示他的信息
void ChatDlg::displayUser(int userid)
{
//为新用户创建toolbutton和聊天室
Client* c = Common::getClientInstance();
RelationUser* user= c->getUserInfById(userid);
ToolButton* toolBtn = new ToolButton(userid);
_toolButtons[userid] = toolBtn;
ChatRoomDlg* chatRoom = new ChatRoomDlg(userid);
_rooms[userid] = chatRoom;
connect(toolBtn,SIGNAL(showChatRoom(int)),this,SLOT(showChatRoom(int)));
//设置显示信息
QString iconPath = QString(":/Resources/registface/") + QString::number(user->face) + ".png";
toolBtn->setIcon(QIcon(iconPath));
toolBtn->setTextRows(QStringList() << user->display << user->sign);
if( FRIEND == user->relation )
{
_layoutFriend->addWidget(toolBtn);
}
else if( BLACK == user->relation )
{
_layoutBlack->addWidget(toolBtn);
}
else if( STRANGER == user->relation )
{
_layoutStranger->addWidget(toolBtn);
}
}
2、用户关系改变
改变用户之间的好友关系
void ChatDlg::changeUserRelation(ToolButton* relationUser,int oldRelation,int newRelation)
{
Q_UNUSED(oldRelation);
Client* c = Common::getClientInstance();
c->getUserInfById(relationUser->getUserid())->relation = newRelation;
if( FRIEND == newRelation )
{
_layoutFriend->addWidget(relationUser);
}
else if( BLACK == newRelation )
{
_layoutBlack->addWidget(relationUser);
}
else if( STRANGER == newRelation )
{
_layoutStranger->addWidget(relationUser);
}
}
3、通信消息处理
void ChatDlg::haveTalkMessage(int userid,QString talk)
{
_rooms[userid]->doTalkMessage( talk );
if(activeRoom != _rooms[userid] )
{
//为方便用户读取新消息,将有消息的toolbutton设置特殊stylesheet提醒用户
_toolButtons[userid]->setStyleSheet("background-color: rgb(170, 255, 255);");
}
Client* c = Common::getClientInstance();
//将聊天消息表示在toolbutton上
_toolButtons[userid]->setTextRows(QStringList()<<c->getDisplay()<<c->getSign()<<talk);
}
4、用户下线处理
其他用用户下线后的处理
void ChatDlg::userOffline(int userid)
{
//取得下线用户的layou后,删除
Client* c = Common::getClientInstance();
RelationUser* userInf = c->getUserInfById(userid);
QVBoxLayout* userLayout;
if( FRIEND == userInf->relation )
{
userLayout = _layoutFriend;
}
else if( BLACK == userInf->relation )
{
userLayout = _layoutBlack;
}
else if( STRANGER == userInf->relation )
{
userLayout = _layoutStranger;
}
userLayout->removeWidget(_toolButtons[userid]);
//清理结构体
_toolButtons[userid]->close();
_toolButtons.remove(userid);
_rooms[userid]->close();
_rooms.remove(userid);
}
5、下线界面处理
用户下线后除了关系消息处理外,界面也是需要处理的。
void ChatDlg::OfflineSuccess()
{
//offline成功后,关闭所有窗口
foreach(ChatRoomDlg* cr, _rooms)
{
cr->close();
}
close();
}
聊天类型消息区别
1、聊天消息格式
//表示聊天信息
void ChatRoomDlg::doTalkMessage(QString message)
{
ui->txtbro_msg->setTextColor(Qt::blue);
QFont font = ui->txtbro_msg->font();
font.setPointSize(12);
ui->txtbro_msg->setFont(font);
QString time = QDateTime::currentDateTime().toString("hh:mm:ss");
QString dispName = Common::getClientInstance()->getUserInfById( _userid )->display;
ui->txtbro_msg->append(time + tr(" [") + dispName + tr("] 对你说:"));
ui->txtbro_msg->append(message);
}
2、消息发送
//发送消息,并表示在本聊天室中
void ChatRoomDlg::on_tb_sendMsg_clicked()
{
QString message = ui->txtEdt_msg->toHtml();
ui->txtbro_msg->setTextColor(Qt::blue);
QFont font = ui->txtbro_msg->font();
font.setPointSize(12);
ui->txtbro_msg->setFont(font);
QString time = QDateTime::currentDateTime().toString("hh:mm:ss");
QString dispName = Common::getClientInstance()->getUserInfById( _userid )->display;
ui->txtbro_msg->append(time + tr("你对 [") + dispName + tr("] 说:"));
ui->txtbro_msg->append(message);
Client* c = Common::getClientInstance();
c->sendChatMessage(_userid,ui->txtEdt_msg->toPlainText());
ui->txtEdt_msg->clear();
ui->txtEdt_msg->setFocus();
}
3、聊天消息基本格式
//发送聊天信息
void Client::sendChatMessage(int receiverUserid,QString message)
{
QMap<QString,QString> msg;
msg["requestKind"]= QString::number(TALK);
msg["receiver"] = QString::number(receiverUserid);
msg["message"]= message;
_clientSocket->sendMessage(msg);
}
消息类型区分
//处理用户消息
void Client::receiveMessage(QMap<QString,QString> message)
{
int requestKind = message["requestKind"].toInt();
//处理消息的代码过多,才分成函数进行调用
if( REGISTER_SUCCESS == requestKind)
{
//处理注册成功消息
doRegisterSuccess(message);
}
else if(LOGIN_SUCCESS == requestKind )
{
//处理登陆成功消息
doLoginSuccess(message);
}
else if(LOGIN_NO_ACCOUNT == requestKind )
{
//处理登陆失败消息
doLoginNoAccount(message);
}
else if(GET_USER_INF_SUCCESS == requestKind)
{
//处理取得其他用户成功消息
doGetUserInfSuccess(message);
}
else if(USER_ONLINE == requestKind)
{
//处理其他用户上线消息
doUserOnline(message);
}
else if(HAVE_TALK_MESSAGE == requestKind)
{
//处理其他用户发送的消息
doHaveTalkMessage(message);
}
else if(USER_OFFLINE == requestKind)
{
//处理其他用户下线消息
doUserOffline(message);
}
else if(OFFLINE_SUCCESS == requestKind)
{
//处理本用户下线成功消息
doOfflineSuccess(message);
}
return ;
}
聊天基础界面
聊天界面运行效果
客户端通信运行效果.gif服务器客户端系统完整源码
下载地址:
网友评论