Название: Как правильно вызвать метод из наследника QThread? Отправлено: Myav от Декабрь 24, 2006, 19:57 Целый день бьюсь над проблемой:
Имеется клиент-серверное приложение. Наследник QTcpServer'а хранит в QMap<QString, Thread*> имена подключившихся пользователей и указатели на обслуживающие их нити. Как только "правильность" подключившегося пользователя подтверждается, обслуживающая нить (наследник QThread'а) эмитит сигнал clientVerificationDone(QString userName, Thread* thread). Сигнал перехватывает сервер и добавляет пару имя/пользователя в QMap. Беда в том, что иногда нужно передать сообщение от одного пользователя другому... Сейчас реализовано так: получив сообщение от конечного пользователя нить эмитит сигнал messageSended(QByteArray from, QString to, QByteArray message); сигнал обрабатывается сервером в методе forwardMessage(). В методе мы находим указатель на нить получателя и вызываем метод этой нити, который и отсылает сообщение: Код: void Server::incomingConnection(int socketDescriptor) Код: void Server::forwardMessage(QByteArray from, QString to, QByteArray message) Проблема в том, что таким образом конечный пользователь может отослать сообщение только сам себе... forwardMessage() будет запущен в потоке отправителя, а внутри вызывается метод из потока получателя :( Можно как-нибудь явно вызывать threads[to]->sendMessage(from, message) из потока threads[to]? Или может есть другой метод решения проблемы? Название: Как правильно вызвать метод из наследника QThread? Отправлено: Dendy от Декабрь 24, 2006, 21:22 У вас архи-неверньІй подход к решению задачи. Во первьІх не стоит на каждое подключение вьІделять один поток. Во вторьІх отправка сообщения через сигнальІ может привести к потере сообщения, если получатель уничтожится. В третьих, вьІ же не собираетесь создавать на каждьІй тип пакета свой сигнал! Поток и сокет - всего лишь транспортная система для получения данньІх. Их вьІборкой, анализом и обработкой поток сокета заниматься не должен. Тяжёлая логика, такая как передача сообщения пользователю/пользователям/в оффлайн/с фильтрацией на матьІ/и т.п. должна бьІть вьІнесена за передельІ транспортной системьІ.
Пользуйтесь postEvent() со своим типом собьІтия, в котором будет лежать пакет. Из потока с сокетом и в поток с сокетом. Различайте пользователей по идентификаторам. Другой вариант - используйте в потоке менеджер для сокетов как шлюз, что будет принимать пакетьІ через потокобезопастньІе методьІ и асинхронно отдавать их сокетам. Вообще длинная тема. Название: Как правильно вызвать метод из наследника QThread? Отправлено: Myav от Декабрь 25, 2006, 04:17 Dendy, спасибо за ЦУ. Буду разбираться :shock:
|