kmessageclient.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <kdebug.h>
00021 #include <stdio.h>
00022
00023 #include <qbuffer.h>
00024 #include <qtimer.h>
00025
00026 #include "kmessageio.h"
00027 #include "kmessageserver.h"
00028
00029 #include "kmessageclient.h"
00030
00031 class KMessageClientPrivate
00032 {
00033 public:
00034 KMessageClientPrivate ()
00035 : adminID (0), connection (0)
00036 {}
00037
00038 ~KMessageClientPrivate ()
00039 {
00040 delete connection;
00041 }
00042
00043 Q_UINT32 adminID;
00044 QValueList <Q_UINT32> clientList;
00045 KMessageIO *connection;
00046
00047 bool isLocked;
00048 QValueList <QByteArray> delayedMessages;
00049 };
00050
00051 KMessageClient::KMessageClient (QObject *parent, const char *name)
00052 : QObject (parent, name)
00053 {
00054 d = new KMessageClientPrivate ();
00055 d->isLocked = false;
00056 }
00057
00058 KMessageClient::~KMessageClient ()
00059 {
00060 d->delayedMessages.clear();
00061 delete d;
00062 }
00063
00064
00065
00066 void KMessageClient::setServer (const QString &host, Q_UINT16 port)
00067 {
00068 setServer (new KMessageSocket (host, port));
00069 }
00070
00071 void KMessageClient::setServer (KMessageServer *server)
00072 {
00073 KMessageDirect *serverIO = new KMessageDirect ();
00074 setServer (new KMessageDirect (serverIO));
00075 server->addClient (serverIO);
00076 }
00077
00078 void KMessageClient::setServer (KMessageIO *connection)
00079 {
00080 if (d->connection)
00081 {
00082 delete d->connection;
00083 kdDebug (11001) << k_funcinfo << ": We are changing the server!" << endl;
00084 }
00085
00086 d->connection = connection;
00087 if (connection )
00088 {
00089 connect (connection, SIGNAL (received(const QByteArray &)),
00090 this, SLOT (processIncomingMessage(const QByteArray &)));
00091 connect (connection, SIGNAL (connectionBroken()),
00092 this, SLOT (removeBrokenConnection ()));
00093 }
00094 }
00095
00096
00097
00098 Q_UINT32 KMessageClient::id () const
00099 {
00100 return (d->connection) ? d->connection->id () : 0;
00101 }
00102
00103 bool KMessageClient::isAdmin () const
00104 {
00105 return id() != 0 && id() == adminId();
00106 }
00107
00108 Q_UINT32 KMessageClient::adminId () const
00109 {
00110 return d->adminID;
00111 }
00112
00113 const QValueList <Q_UINT32> &KMessageClient::clientList() const
00114 {
00115 return d->clientList;
00116 }
00117
00118 bool KMessageClient::isConnected () const
00119 {
00120 return d->connection && d->connection->isConnected();
00121 }
00122
00123 bool KMessageClient::isNetwork () const
00124 {
00125 return isConnected() ? d->connection->isNetwork() : false;
00126 }
00127
00128 Q_UINT16 KMessageClient::peerPort () const
00129 {
00130 return d->connection ? d->connection->peerPort() : 0;
00131 }
00132
00133 QString KMessageClient::peerName () const
00134 {
00135 return d->connection ? d->connection->peerName() : QString::fromLatin1("localhost");
00136 }
00137
00138
00139
00140 void KMessageClient::sendServerMessage (const QByteArray &msg)
00141 {
00142 if (!d->connection)
00143 {
00144 kdWarning (11001) << k_funcinfo << ": We have no connection yet!" << endl;
00145 return;
00146 }
00147 d->connection->send (msg);
00148 }
00149
00150 void KMessageClient::sendBroadcast (const QByteArray &msg)
00151 {
00152 QByteArray sendBuffer;
00153 QBuffer buffer (sendBuffer);
00154 buffer.open (IO_WriteOnly);
00155 QDataStream stream (&buffer);
00156
00157 stream << static_cast<Q_UINT32> ( KMessageServer::REQ_BROADCAST );
00158 buffer.QIODevice::writeBlock (msg);
00159 sendServerMessage (sendBuffer);
00160 }
00161
00162 void KMessageClient::sendForward (const QByteArray &msg, const QValueList <Q_UINT32> &clients)
00163 {
00164 QByteArray sendBuffer;
00165 QBuffer buffer (sendBuffer);
00166 buffer.open (IO_WriteOnly);
00167 QDataStream stream (&buffer);
00168
00169 stream << static_cast<Q_UINT32>( KMessageServer::REQ_FORWARD ) << clients;
00170 buffer.QIODevice::writeBlock (msg);
00171 sendServerMessage (sendBuffer);
00172 }
00173
00174 void KMessageClient::sendForward (const QByteArray &msg, Q_UINT32 client)
00175 {
00176 sendForward (msg, QValueList <Q_UINT32> () << client);
00177 }
00178
00179
00180
00181
00182 void KMessageClient::processIncomingMessage (const QByteArray &msg)
00183 {
00184 if (d->isLocked)
00185 {
00186 d->delayedMessages.append(msg);
00187 return;
00188 }
00189 if (d->delayedMessages.count() > 0)
00190 {
00191 d->delayedMessages.append (msg);
00192 QByteArray first = d->delayedMessages.front();
00193 d->delayedMessages.pop_front();
00194 processMessage (first);
00195 }
00196 else
00197 {
00198 processMessage(msg);
00199 }
00200 }
00201
00202 void KMessageClient::processMessage (const QByteArray &msg)
00203 {
00204 if (d->isLocked)
00205 {
00206 d->delayedMessages.append(msg);
00207 return;
00208 }
00209 QBuffer in_buffer (msg);
00210 in_buffer.open (IO_ReadOnly);
00211 QDataStream in_stream (&in_buffer);
00212
00213
00214 bool unknown = false;
00215
00216 Q_UINT32 messageID;
00217 in_stream >> messageID;
00218 switch (messageID)
00219 {
00220 case KMessageServer::MSG_BROADCAST:
00221 {
00222 Q_UINT32 clientID;
00223 in_stream >> clientID;
00224 emit broadcastReceived (in_buffer.readAll(), clientID);
00225 }
00226 break;
00227
00228 case KMessageServer::MSG_FORWARD:
00229 {
00230 Q_UINT32 clientID;
00231 QValueList <Q_UINT32> receivers;
00232 in_stream >> clientID >> receivers;
00233 emit forwardReceived (in_buffer.readAll(), clientID, receivers);
00234 }
00235 break;
00236
00237 case KMessageServer::ANS_CLIENT_ID:
00238 {
00239 bool old_admin = isAdmin();
00240 Q_UINT32 clientID;
00241 in_stream >> clientID;
00242 d->connection->setId (clientID);
00243 if (old_admin != isAdmin())
00244 emit adminStatusChanged (isAdmin());
00245 }
00246 break;
00247
00248 case KMessageServer::ANS_ADMIN_ID:
00249 {
00250 bool old_admin = isAdmin();
00251 in_stream >> d->adminID;
00252 if (old_admin != isAdmin())
00253 emit adminStatusChanged (isAdmin());
00254 }
00255 break;
00256
00257 case KMessageServer::ANS_CLIENT_LIST:
00258 {
00259 in_stream >> d->clientList;
00260 }
00261 break;
00262
00263 case KMessageServer::EVNT_CLIENT_CONNECTED:
00264 {
00265 Q_UINT32 id;
00266 in_stream >> id;
00267
00268 if (d->clientList.contains (id))
00269 kdWarning (11001) << k_funcinfo << ": Adding a client that already existed!" << endl;
00270 else
00271 d->clientList.append (id);
00272
00273 emit eventClientConnected (id);
00274 }
00275 break;
00276
00277 case KMessageServer::EVNT_CLIENT_DISCONNECTED:
00278 {
00279 Q_UINT32 id;
00280 Q_INT8 broken;
00281 in_stream >> id >> broken;
00282
00283 if (!d->clientList.contains (id))
00284 kdWarning (11001) << k_funcinfo << ": Removing a client that doesn't exist!" << endl;
00285 else
00286 d->clientList.remove (id);
00287
00288 emit eventClientDisconnected (id, bool (broken));
00289 }
00290 break;
00291
00292 default:
00293 unknown = true;
00294 }
00295
00296 if (!unknown && !in_buffer.atEnd())
00297 kdWarning (11001) << k_funcinfo << ": Extra data received for message ID " << messageID << endl;
00298
00299 emit serverMessageReceived (msg, unknown);
00300
00301 if (unknown)
00302 kdWarning (11001) << k_funcinfo << ": received unknown message ID " << messageID << endl;
00303 }
00304
00305 void KMessageClient::processFirstMessage()
00306 {
00307 if (d->isLocked)
00308 {
00309 return;
00310 }
00311 if (d->delayedMessages.count() == 0)
00312 {
00313 kdDebug(11001) << k_funcinfo << ": no messages delayed" << endl;
00314 return;
00315 }
00316 QByteArray first = d->delayedMessages.front();
00317 d->delayedMessages.pop_front();
00318 processMessage (first);
00319 }
00320
00321 void KMessageClient::removeBrokenConnection ()
00322 {
00323 kdDebug (11001) << k_funcinfo << ": timer single shot for removeBrokenConnection"<<this << endl;
00324
00325 QTimer::singleShot( 0, this, SLOT(removeBrokenConnection2()) );
00326 return;
00327 }
00328
00329
00330 void KMessageClient::removeBrokenConnection2 ()
00331 {
00332 kdDebug (11001) << k_funcinfo << ": Broken:Deleting the connection object"<<this << endl;
00333
00334 emit aboutToDisconnect(id());
00335 delete d->connection;
00336 d->connection = 0;
00337 d->adminID = 0;
00338 emit connectionBroken();
00339 kdDebug (11001) << k_funcinfo << ": Broken:Deleting the connection object DONE" << endl;
00340 }
00341
00342 void KMessageClient::disconnect ()
00343 {
00344 kdDebug (11001) << k_funcinfo << ": Disconnect:Deleting the connection object" << endl;
00345
00346 emit aboutToDisconnect(id());
00347 delete d->connection;
00348 d->connection = 0;
00349 d->adminID = 0;
00350 emit connectionBroken();
00351 kdDebug (11001) << k_funcinfo << ": Disconnect:Deleting the connection object DONE" << endl;
00352 }
00353
00354 void KMessageClient::lock ()
00355 {
00356 d->isLocked = true;
00357 }
00358
00359 void KMessageClient::unlock ()
00360 {
00361 d->isLocked = false;
00362 for (unsigned int i = 0; i < d->delayedMessages.count(); i++)
00363 {
00364 QTimer::singleShot(0, this, SLOT(processFirstMessage()));
00365 }
00366 }
00367
00368 unsigned int KMessageClient::delayedMessageCount() const
00369 {
00370 return d->delayedMessages.count();
00371 }
00372
00373 #include "kmessageclient.moc"
|