这个实例使用QWebSocket和QWebSocketServer去构造WebSocket协议的极简聊天室。
官方对于这个实例给出的文档方面的介绍就这么多,下面是对应的代码,我自己补充下:
文件一共如下:
我们由简入深分析下,首先是simplechat.pro
QT = websockets
TARGET = chatserver
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES +=
main.cpp
chatserver.cpp
HEADERS +=
chatserver.h
EXAMPLE_FILES += chatclient.html
target.path = $$[QT_INSTALL_EXAMPLES]/websockets/simplechat
INSTALLS += target
这里主要是包含websockets模块,使用的语法是 QT = websockets
main.cpp就是实例化ChatServer在此不再说明。
下面是chartserver.h和chartserver.cpp
#ifndef CHATSERVER_H #define CHATSERVER_H #include#include QT_FORWARD_DECLARE_CLASS(QWebSocketServer) QT_FORWARD_DECLARE_CLASS(QWebSocket) QT_FORWARD_DECLARE_CLASS(QString) class ChatServer : public QObject { Q_OBJECT public: explicit ChatServer(quint16 port, QObject *parent = nullptr); ~ChatServer() override; private slots: void onNewConnection(); void processMessage(const QString &message); void socketDisconnected(); private: QWebSocketServer *m_pWebSocketServer; QList m_clients; }; #endif //CHATSERVER_H
#include "chatserver.h" #include#include #include using namespace std; QT_USE_NAMESPACE static QString getIdentifier(QWebSocket *peer) { return QStringLiteral("%1:%2").arg(peer->peerAddress().toString(), QString::number(peer->peerPort())); } //! [constructor] ChatServer::ChatServer(quint16 port, QObject *parent) : QObject(parent), m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Chat Server"), QWebSocketServer::NonSecureMode, this)) { if (m_pWebSocketServer->listen(QHostAddress::Any, port)) { QTextStream(stdout) << "Chat Server listening on port " << port << 'n'; connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &ChatServer::onNewConnection); } } ChatServer::~ChatServer() { m_pWebSocketServer->close(); } //! [constructor] //! [onNewConnection] void ChatServer::onNewConnection() { auto pSocket = m_pWebSocketServer->nextPendingConnection(); QTextStream(stdout) << getIdentifier(pSocket) << " connected!n"; pSocket->setParent(this); connect(pSocket, &QWebSocket::textMessageReceived, this, &ChatServer::processMessage); connect(pSocket, &QWebSocket::disconnected, this, &ChatServer::socketDisconnected); m_clients << pSocket; } //! [onNewConnection] //! [processMessage] void ChatServer::processMessage(const QString &message) { QWebSocket *pSender = qobject_cast (sender()); for (QWebSocket *pClient : qAsConst(m_clients)) { if (pClient != pSender) //don't echo message back to sender pClient->sendTextMessage(message); } } //! [processMessage] //! [socketDisconnected] void ChatServer::socketDisconnected() { QWebSocket *pClient = qobject_cast (sender()); QTextStream(stdout) << getIdentifier(pClient) << " disconnected!n"; if (pClient) { m_clients.removeAll(pClient); pClient->deleteLater(); } } //! [socketDisconnected]
这里解释几个点:
①m_pWebSocketServer是QWebSocketServer,指定其名和mode以及开通的端口号;
②newConnection中,使用m_pWebSocketServer获取nextPendingConnection,然后得到这个与客户端相连的socket后,设置信号与槽。
③processMessage,将获取到用户发来的信号与槽,发送给所有连接到服务器的用户。
④socketDisconnect,当用户断开连接后,把其用户移除m_clients。
下面是chartclient.html
WebSocket Chat Client
WebSocket Chat Client
Host:
这个html代码,浏览器运行后,会创建一个websocket连接到服务端上,然后进行文本串的交互。



