美文网首页
Qt 局域网通讯系统——客户端间通信(综合)

Qt 局域网通讯系统——客户端间通信(综合)

作者: 飞扬code | 来源:发表于2019-08-02 09:34 被阅读0次

客户端间通信功能预览

聊天通信效果

信号关联机制

整体的逻辑关系实现

//用户上线显示(包括自身和其他用户)
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

服务器客户端系统完整源码

下载地址:

相关文章

网友评论

      本文标题:Qt 局域网通讯系统——客户端间通信(综合)

      本文链接:https://www.haomeiwen.com/subject/bslkdctx.html