如何将数据发送到多线程服务器上的特定客户端
How to send data to a specific client on a multithreaded server
我正在尝试构建一个多线程服务器。我遇到的问题是发出的信号将消息发送给所有客户端,而不是特定线程上的特定客户端。
我试图通过创建线程的 QList 来解决问题,但我该如何具体连接它们?当发出信号时,它会唤醒我所有的线程,每个连接都会使问题变得更糟,因为客户端在连接时是动态分配的。
代码:
void NetworkServer::incomingConnection(qintptr socketDescriptor)
{
QThread *thread = new QThread;
threadhandle *session = new threadhandle;
QObject::connect(this, &NetworkServer::stopped, session, &threadhandle::close);
QObject::connect(this, &NetworkServer::stopped, thread, &threadhandle::quit);
QObject::connect(session, &threadhandle::closed, thread, &threadhandle::quit);
QObject::connect(thread, &QThread::started, this, &NetworkServer::threadStarted, Qt::DirectConnection);
QObject::connect(thread, &QThread::finished, this, &NetworkServer::threadFinished, Qt::DirectConnection);
QObject::connect(thread, &QThread::finished, session, &QObject::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
//the problem is here, I can send message to all clients connected, but how to specifiy a thread/client???
QObject::connect(this, &NetworkServer::sendMsgToThread, session, &threadhandle::sendMsgToClient);
thread->start();
session->moveToThread(thread);
QMetaObject::invokeMethod(session, "open", Qt::QueuedConnection, Q_ARG(qintptr, socketDescriptor));
更新 - 40 分钟后 - 问题已解决
很抱歉没有提供更多细节,基本上我正在构建一个简单的客户端-服务器关系。消息以文本格式从服务器 GUI 行发送到特定客户端。
经过一番思考,我想到了一个解决方案。
所以对于每个新线程,我们将其会话附加到:QListsessionList
之后我们将编辑 sendMsgToClient()
// user clicks on Send Message button in GUI
void NetworkServer::sendMsgToClient(int clientNum, QString msg)
{
//connect the signal to a specific thread, clientNum is selected from a table in mainWindow GUI where the NetworkServer class is initiated
QObject::connect(this, &NetworkServer::sendMsgToThread, sessionList.at(clientNum), &threadhandle::sendMsgToClient);
//emit the signal to specific thread
emit sendMsgToThread(clientNum, msg);
//disconnect the signal, since it is no longer needed
QObject::disconnect(this, &NetworkServer::sendMsgToThread, sessionList.at(clientNum), &threadhandle::sendMsgToClient);
}
如果没有构建和呈现您的确切问题的 MRE,很难说真的。但是,从上下文猜测:不知道 NetworkServer::sendMsgToThread
或 threadhandle::sendMsgToClient
是如何实现的,但我想你可以存储线程 ID/index/any 其他标识符,然后仅将它传递给特定线程,可能通过一些代理对象?
要点是,sendMsgToThread 连接到多个槽,这可能不是您想要的;相反,需要以某种方式区分那些单个会话线程对,例如按线程 ID/its 列表中的索引,无论如何。
我想你可以将 session
和 thread
包装在其他一些 class 中,服务器将通过上述一些 ID 存储(和引用)它们,它将消息转发给工作(会话)对象。但是,如果至少不了解您的代码架构的基本知识,我无法真正判断。
我正在尝试构建一个多线程服务器。我遇到的问题是发出的信号将消息发送给所有客户端,而不是特定线程上的特定客户端。
我试图通过创建线程的 QList 来解决问题,但我该如何具体连接它们?当发出信号时,它会唤醒我所有的线程,每个连接都会使问题变得更糟,因为客户端在连接时是动态分配的。
代码:
void NetworkServer::incomingConnection(qintptr socketDescriptor)
{
QThread *thread = new QThread;
threadhandle *session = new threadhandle;
QObject::connect(this, &NetworkServer::stopped, session, &threadhandle::close);
QObject::connect(this, &NetworkServer::stopped, thread, &threadhandle::quit);
QObject::connect(session, &threadhandle::closed, thread, &threadhandle::quit);
QObject::connect(thread, &QThread::started, this, &NetworkServer::threadStarted, Qt::DirectConnection);
QObject::connect(thread, &QThread::finished, this, &NetworkServer::threadFinished, Qt::DirectConnection);
QObject::connect(thread, &QThread::finished, session, &QObject::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
//the problem is here, I can send message to all clients connected, but how to specifiy a thread/client???
QObject::connect(this, &NetworkServer::sendMsgToThread, session, &threadhandle::sendMsgToClient);
thread->start();
session->moveToThread(thread);
QMetaObject::invokeMethod(session, "open", Qt::QueuedConnection, Q_ARG(qintptr, socketDescriptor));
更新 - 40 分钟后 - 问题已解决
很抱歉没有提供更多细节,基本上我正在构建一个简单的客户端-服务器关系。消息以文本格式从服务器 GUI 行发送到特定客户端。
经过一番思考,我想到了一个解决方案。
所以对于每个新线程,我们将其会话附加到:QList
之后我们将编辑 sendMsgToClient()
// user clicks on Send Message button in GUI
void NetworkServer::sendMsgToClient(int clientNum, QString msg)
{
//connect the signal to a specific thread, clientNum is selected from a table in mainWindow GUI where the NetworkServer class is initiated
QObject::connect(this, &NetworkServer::sendMsgToThread, sessionList.at(clientNum), &threadhandle::sendMsgToClient);
//emit the signal to specific thread
emit sendMsgToThread(clientNum, msg);
//disconnect the signal, since it is no longer needed
QObject::disconnect(this, &NetworkServer::sendMsgToThread, sessionList.at(clientNum), &threadhandle::sendMsgToClient);
}
如果没有构建和呈现您的确切问题的 MRE,很难说真的。但是,从上下文猜测:不知道 NetworkServer::sendMsgToThread
或 threadhandle::sendMsgToClient
是如何实现的,但我想你可以存储线程 ID/index/any 其他标识符,然后仅将它传递给特定线程,可能通过一些代理对象?
要点是,sendMsgToThread 连接到多个槽,这可能不是您想要的;相反,需要以某种方式区分那些单个会话线程对,例如按线程 ID/its 列表中的索引,无论如何。
我想你可以将 session
和 thread
包装在其他一些 class 中,服务器将通过上述一些 ID 存储(和引用)它们,它将消息转发给工作(会话)对象。但是,如果至少不了解您的代码架构的基本知识,我无法真正判断。