00001
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"