QwebSocket即时通信

最近因为项目原因。准备前后端进行分离。所有的接口全部通过websocket进行交互。
所以干脆先试写一个demo。
使用websocket进行通信。需要有服务端和客户端。(客户端和服务端是2个独立程序)

客户端

客户端只负责发消息和接受消息。
.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QProgressBar>
#include <QWebSocket>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void Init();
    void Connect();

protected slots:
    void onConnectClicked();  //点击连接按钮触发事件
    void onSendClicked();  //发送数据
    void onConnectServer(); //连接服务端
    void onDisConnectServer(); //断开连接
    void onReceiverData(const QString &msg); //接受数据。可以是json。使用qbytearray进行转化和解码

private:

    QLineEdit *m_pAddressEdit=nullptr;
    QTextEdit *m_pTextEdit=nullptr;
    QPushButton *m_pConnectBtn=nullptr;
    QPushButton *m_pSendBtn=nullptr;

    QWebSocket *m_pReceiverSocket=nullptr;

};
#endif // WIDGET_H

.cpp

#include "widget.h"
#include <QHBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->resize(800,600);
    Init();
    Connect();

}

Widget::~Widget()
{
}

void Widget::Init()
{
    m_pAddressEdit=new QLineEdit(this);
    m_pTextEdit=new QTextEdit(this);
    m_pConnectBtn=new QPushButton(tr("Connect"),this);
    m_pSendBtn=new QPushButton(tr("Send"),this);

    m_pAddressEdit->setFixedSize(230,27);
    m_pConnectBtn->setFixedSize(150,27);
    m_pSendBtn->setFixedSize(150,27);

    QWidget *titleWgt=new QWidget(this);
    QHBoxLayout *titleLayout=new QHBoxLayout(this);
    titleLayout->addWidget(m_pAddressEdit);
    titleLayout->addWidget(m_pConnectBtn);
    titleLayout->addWidget(m_pSendBtn);
    titleLayout->setMargin(10);
    titleLayout->setSpacing(10);
    titleWgt->setLayout(titleLayout);

    QVBoxLayout *mainLayout=new QVBoxLayout(this);
    mainLayout->addWidget(titleWgt);
    mainLayout->addWidget(m_pTextEdit);
    mainLayout->setMargin(0);
    mainLayout->setSpacing(0);
    this->setLayout(mainLayout);

    m_pSendBtn->setEnabled(false);

    m_pReceiverSocket=new QWebSocket;
    m_pReceiverSocket->setParent(this);

}

void Widget::Connect()
{
    connect(m_pConnectBtn,&QPushButton::clicked,this,&Widget::onConnectClicked);
    connect(m_pSendBtn,&QPushButton::clicked,this,&Widget::onSendClicked);
    connect(m_pReceiverSocket,&QWebSocket::connected,this,&Widget::onConnectServer);
    connect(m_pReceiverSocket,&QWebSocket::disconnected,this,&Widget::onDisConnectServer);
    connect(m_pReceiverSocket,&QWebSocket::textMessageReceived,this,&Widget::onReceiverData);
}

void Widget::onConnectClicked()
{
    QString strAddress=m_pAddressEdit->text();
    if(strAddress!="")
    {
        m_pReceiverSocket->open(QUrl(strAddress));  /* ws://localhost:2022 */ 
        											//localhost可变为ip地址,这里只是方便测试
        											//冒号后面是端口号
    }
}
void Widget::onSendClicked()
{
    if(!m_pTextEdit->toPlainText().isEmpty())   
    {
        m_pReceiverSocket->sendTextMessage(m_pTextEdit->toPlainText());
    }

}

void Widget::onConnectServer()
{
    m_pConnectBtn->setEnabled(false);
    m_pSendBtn->setEnabled(true);
    m_pTextEdit->append(QString("Address:%1  Port:%2").arg(m_pReceiverSocket->localAddress().toString()).arg(m_pReceiverSocket->localPort()));
}

void Widget::onDisConnectServer()
{
    m_pConnectBtn->setEnabled(true);
    m_pSendBtn->setEnabled(false);
    m_pTextEdit->append("DisConnet To Server");
}

void Widget::onReceiverData(const QString &msg)
{
    m_pTextEdit->append(msg);
}


服务端

服务端需要有一个websocketserver进行监听端口,当有消息过来可进行处理。
.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QProgressBar>
#include <QWebSocket>
#include <QWebSocketServer>
#include <vector>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void Init();
    void Connect();



signals:
    void sendMessage(QString);

protected slots:
    void onListenClicked();  //监听事件触发
    void onNewConnection();  //有新的连接加入

private:
    void ClearClient();  //清除所有连接

private:
    QLineEdit *m_pAddressEdit=nullptr;
    QLineEdit *m_pPortEdit=nullptr;
    QTextEdit *m_pTextEdit=nullptr;
    QPushButton *m_pConnectBtn=nullptr;
    QPushButton *m_pSendBtn=nullptr;

    QWebSocketServer *m_pServerSocket=nullptr;

    QVector<QWebSocket *>ClientList;

};
#endif // WIDGET_H

.cpp

#include "widget.h"
#include <QHBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    Init();
    Connect();
}

Widget::~Widget()
{
	//这里是重点。一定要在析构函数中对server进行关闭。不然程序会奔溃
    ClearClient();
    m_pServerSocket->close();
}

void Widget::Init()
{
    m_pAddressEdit=new QLineEdit(this);
    m_pPortEdit=new QLineEdit(this);
    m_pTextEdit=new QTextEdit(this);
    m_pConnectBtn=new QPushButton(tr("Listen"),this);
    m_pSendBtn=new QPushButton(tr("Send"),this);

    m_pAddressEdit->setFixedSize(230,27);
    m_pPortEdit->setFixedSize(100,27);
    m_pConnectBtn->setFixedSize(150,27);
    m_pSendBtn->setFixedSize(150,27);

    QWidget *titleWgt=new QWidget(this);
    QHBoxLayout *titleLayout=new QHBoxLayout(this);
    titleLayout->addWidget(m_pAddressEdit);
    titleLayout->addWidget(m_pPortEdit);
    titleLayout->addWidget(m_pConnectBtn);
    titleLayout->addWidget(m_pSendBtn);
    titleLayout->setMargin(10);
    titleLayout->setSpacing(10);
    titleWgt->setLayout(titleLayout);

    QVBoxLayout *mainLayout=new QVBoxLayout(this);
    mainLayout->addWidget(titleWgt);
    mainLayout->addWidget(m_pTextEdit);
    mainLayout->setMargin(0);
    mainLayout->setSpacing(0);
    this->setLayout(mainLayout);

    m_pSendBtn->setEnabled(false);


    //server Listen
    m_pServerSocket=new QWebSocketServer("Server",QWebSocketServer::NonSecureMode,this);
    m_pSendBtn->setEnabled(false);

}

void Widget::Connect()
{
    connect(m_pConnectBtn,&QPushButton::clicked,this,&Widget::onListenClicked);
    connect(m_pServerSocket,&QWebSocketServer::newConnection,this,&Widget::onNewConnection);
    connect(m_pSendBtn,&QPushButton::clicked,[this](){
            if(!m_pTextEdit->toPlainText().isEmpty())
                emit sendMessage(m_pTextEdit->toPlainText());
        });
}

void Widget::onListenClicked()
{
    if(m_pConnectBtn->text()!="Listen")
    {
        m_pSendBtn->setEnabled(false);
        m_pConnectBtn->setText("Listen");
        m_pServerSocket->close();
        ClearClient();
    }
    else
    {
        QHostAddress address;
        if(m_pAddressEdit->text()=="Any")  //可进行监听任意地址
        {
            address=QHostAddress::Any;
        }
        else
        {
            address=QHostAddress(m_pAddressEdit->text());  //监听指定地址
        }
        if(m_pServerSocket->listen(address,m_pPortEdit->text().toUInt())){
                        m_pSendBtn->setEnabled(true);  //成功监听。
                        m_pConnectBtn->setText("Dislisten");
                    }
    }
}

void Widget::onNewConnection()
{
	//监听只能监听一个ip地址。不能同时监听多个
    QWebSocket *socket=m_pServerSocket->nextPendingConnection();
    if(!socket)
        return;
    m_pTextEdit->append(QString("[new Connect] Address:%1    prot:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
    ClientList.push_back(socket);

    connect(socket,&QWebSocket::textMessageReceived,[this](const QString &msg){
            m_pTextEdit->append(msg);
        });

    connect(this,&Widget::sendMessage,socket,&QWebSocket::sendTextMessage);

    connect(socket,&QWebSocket::disconnected,[this,socket](){
            ClientList.removeAll(socket);
            socket->deleteLater();
    });
}

void Widget::ClearClient()
{
    for(int i=0;i<ClientList.size();++i)
    {
        ClientList[i]->disconnect();
        ClientList[i]->close();
    }
    ClientList.clear();

}


效果图:
在这里插入图片描述
其实我偷了个懒。应该使用2个texteit进行接受和发送。我写在一个里面。自己修改下就可以进行使用。
觉得有用记得点个赞。
ヾ( ̄▽ ̄)ByeBye

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油吧,小杜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值