最近因为项目原因。准备前后端进行分离。所有的接口全部通过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