Ok, the long awaited config wizard is here (at least in a very basic state). There...
[quassel.git] / src / contrib / libqxt-2007-10-24 / src / network / qxtrpcpeer.h
1 /****************************************************************************
2  **
3  ** Copyright (C) Qxt Foundation. Some rights reserved.
4  **
5  ** This file is part of the QxtNetwork module of the Qt eXTension library
6  **
7  ** This library is free software; you can redistribute it and/or modify it
8  ** under the terms of th Common Public License, version 1.0, as published by
9  ** IBM.
10  **
11  ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12  ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13  ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14  ** FITNESS FOR A PARTICULAR PURPOSE.
15  **
16  ** You should have received a copy of the CPL along with this file.
17  ** See the LICENSE file and the cpl1.0.txt file included with the source
18  ** distribution for more information. If you did not receive a copy of the
19  ** license, contact the Qxt Foundation.
20  **
21  ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
22  **
23  ****************************************************************************/
24
25 #ifndef QXTRPCPEER
26 #define QXTRPCPEER
27
28 #include <QObject>
29 #include <QList>
30 #include <QVariant>
31 #include <QPair>
32 #include <QString>
33 #include <QHostAddress>
34 #include <qxtpimpl.h>
35 #include <qxtglobal.h>
36 class QTcpSocket;
37 class QxtRPCPeerPrivate;
38 /*!
39  * \class QxtRPCPeer QxtRPCPeer
40  * \ingroup QxtNetwork
41  * \brief Transmits Qt signals over a network connection
42  *
43  * QxtRPCPeer is a tool that encapsulates Qt signals and transmits them over a network connection.
44  * The signal is subsequently re-emitted on the receiving end of the connection.
45  *
46  * QxtRPCPeer can operate in peer-to-peer mode (that is, one-to-one) or client-server (that is, one-to-many) mode.
47  * In peer or server mode, QxtRPCPeer can listen for and accept incoming connections. In peer or client mode,
48  * QxtRPCPeer can connect to a listening peer or server.
49  *
50  * All data types used in attached signals and slots must be declared and registered with QMetaType using
51  * Q_DECLARE_METATYPE and qRegisterMetaType, and they must have stream operators registered with qRegisterMetaTypeStreamOperators.
52  *
53  * The limits on the number of parameters passed to call() and related functions are a restriction of Qt,
54  * which limits parameters on a signal or slot to 10.
55  */
56 class QXT_NETWORK_EXPORT QxtRPCPeer : public QObject
57 {
58     Q_OBJECT
59 public:
60
61     /*!
62      * This enum is used with the \a setRPCType() to describe the role played in a connection. It is also returned by \a rpcType().
63      */
64     enum RPCTypes
65     {
66         Server,                               /**< Listen for clients and accept multiple connections. */
67         Client,                               /**< Connect to a server. */
68         Peer                                  /**< Listen for a connection or connect to a peer. */
69     };
70
71     /*!
72      * Creates a QxtRPCPeer object with the given parent. Unless changed later, this object will use Peer mode and QTcpSocket for its I/O device.
73      */
74     QxtRPCPeer(QObject* parent = 0);
75
76     /*!
77      * Creates a QxtRPCPeer object with the given parent and type. Unless changed later, this object will use QTcpSocket for its I/O device.
78      */
79     QxtRPCPeer(RPCTypes type, QObject* parent = 0);
80
81     /*!
82      * Creates a QxtRPCPeer object with the given parent and type and connects it to the specified I/O device.
83      *
84      * Note that the I/O device must already be opened for reading and writing. This constructor cannot be used for Server mode.
85      */
86     QxtRPCPeer(QIODevice* device, RPCTypes type = QxtRPCPeer::Peer, QObject* parent = 0);
87
88     /*!
89      * Sets the RPC type.
90      *
91      * Attempting to change the RPC type while listening or connected will be ignored with a warning.
92      */
93     void setRPCType(RPCTypes type);
94
95     /*!
96      * Returns the current RPC type.
97      */
98     RPCTypes rpcType() const;
99
100     /*!
101      * Connects to the specified peer or server on the selected port.
102      *
103      * When the connection is complete, the \a peerConnected() signal will be emitted.  If an error occurs, the \a peerError() signal will be emitted.
104      */
105     void connect(QHostAddress addr, int port = 80);
106
107     /*!
108      * Listens on the specified interface on the specified port for connections.
109      *
110      * Attempting to listen while in Client mode or while connected in Peer mode will be ignored with a warning.  In Peer mode, only one connection
111      * can be active at a time. Additional incoming connections while connected to a peer will be dropped. When a peer connects, the \a peerConnected()
112      * signal will be emitted. In Server mode, multiple connections can be active at a time. Each client that connects will be provided a unique ID,
113      * included in the \a clientConnected() signal that will be emitted.
114      */
115     bool listen(QHostAddress iface = QHostAddress::Any, int port = 80);
116
117     /*!
118      * Disconnects from a server, client, or peer.
119      *
120      * Servers must provide a client ID, provided by the \a clientConnected() signal; clients and peers must not.
121      */
122     void disconnectPeer(quint64 id = -1);
123
124     /*!
125      * Disconnects from all clients, or from the server or peer.
126      */
127     void disconnectAll();
128
129     /*!
130      * Stops listening for connections. Any connections still open will remain connected.
131      */
132     void stopListening();
133
134     /*!
135      * Returns a list of client IDs for all connected clients.
136      */
137     QList<quint64> clients() const;
138
139     /*!
140      * Attaches the given signal.
141      *
142      * When the attached signal is emitted, it will be transmitted to all connected servers, clients, or peers.
143      * If an optional rpcFunction is provided, it will be used in place of the name of the transmitted signal.
144      * Use the SIGNAL() macro to specify the signal, just as you would for QObject::connect().
145      *
146      * Like QObject::connect(), attachSignal returns false if the connection cannot be established.
147      */
148     bool attachSignal(QObject* sender, const char* signal, const QByteArray& rpcFunction = QByteArray());
149
150     /*!
151      * Attaches the given slot.
152      *
153      * When a signal with the name given by rpcFunction is received from the network, the attached slot is executed.
154      * Use the SLOT() macro to specify the slot, just as you would for QObject::connect().
155      *
156      * Like QObject::connect(), attachSignal returns false if the connection cannot be established.
157      *
158      * \Note In Server mode, the first parameter of the slot must be int id. The parameters of the signal follow.
159      * For example, SIGNAL(mySignal(QString)) from the client connects to SLOT(mySlot(int, QString)) on the server.
160      */
161     bool attachSlot(const QByteArray& rpcFunction, QObject* recv, const char* slot);
162
163     /*!
164      * Detaches all signals and slots for the given object.
165      */
166     void detachObject(QObject* obj);
167
168
169     /*!
170      * Returns the current used iodevice (might be asocket or a custom iodevie) in client and peer mode.
171      * returns 0 for server mode
172      */
173     QIODevice * socket();
174
175 public slots:
176     /*!
177      * Sends the signal fn with the given parameter list to the server or peer.
178      *
179      * This function accepts up to 9 QVariant parameters.
180      *
181      * The receiver is not obligated to act upon the signal. If no server or peer is connected, the call is ignored.
182      * In particular, this function does nothing in Server mode.
183      */
184     void call(const char *signal, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(),
185               QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant(), QVariant p9 = QVariant());
186
187     /*!
188      * Sends the signal with the given parameter list to the provided list of clients.
189      *
190      * This function accepts up to 8 QVariant parameters.
191      *
192      * The receivers are not obligated to act upon the signal. If no client is connected with a provided ID, the ID
193      * is ignored with a warning.
194      */
195     void callClientList(QList<quint64> ids, QString fn, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(),
196                         QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant());
197
198     /*!
199      * Sends the signal fn with the given parameter list to the specified client.
200      *
201      * This function accepts up to 8 QVariant parameters.
202      *
203      * The receiver is not obligated to act upon the signal. If no client with the given ID is connected, the call will be ignored with a warning.
204      */
205     void callClient(quint64 id, QString fn, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(),
206                     QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant());
207
208     /*!
209      * Sends the signal fn with the given parameter list to all connected clients except for the client specified.
210      *
211      * This function accepts up to 8 QVariant parameters.
212      *
213      * The receiver is not obligated to act upon the signal. This function is useful for rebroadcasting a signal from one client
214      * to all other connected clients.
215      */
216     void callClientsExcept(quint64 id, QString fn, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(),
217                            QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant());
218
219     /*!
220      * Detaches all signals and slots for the object that emitted the signal connected to detachSender().
221      */
222     void detachSender();
223
224     /*!
225      * gives Access to the socket of the client \n
226      * usefull to get information about the client, like adress, port, etc..\n
227      * returns 0 when not in server mode or if the client \p id does not exist.
228      */
229
230     const QTcpSocket * clientSocket(quint64 id) const;
231
232     /*!
233      * returns alist of all clients currently connected \n
234      * returns an empty List when not in server mode
235      */
236
237     QList<quint64> clients();
238
239 signals:
240     /*!
241      * This signal is emitted after a successful connection to or from a peer or server.
242      */
243     void peerConnected();
244
245     /*!
246      * This signal is emitted after a successful connection from a client.
247      *
248      * The given ID is used for disconnectPeer(), callClient(), and related functions.
249      */
250     void clientConnected(quint64 id);
251
252     /*!
253      * This signal is emitted when a peer or server is disconnected.
254      */
255     void peerDisconnected();
256
257     /*!
258      * This signal is emitted when a client disconnects. The given ID is no longer valid.
259      */
260     void clientDisconnected(quint64 id);
261
262     /*!
263      * This signal is emitted whenever an error occurs on a socket.
264      *
265      * Currently, no information about the socket that raised the error is available.
266      */
267     void peerError(QAbstractSocket::SocketError);
268
269 protected:
270     /*!
271      * Serializes a signal into a form suitable for transmitting over the network.
272      *
273      * Reimplement this function in a subclass to allow QxtRPCPeer to use a different protocol.
274      */
275     virtual QByteArray serialize(QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) const;
276
277     /*!
278      * Deserializes network data into a signal name and a list of parameters.
279      *
280      * Reimplement this function in a subclass to allow QxtRPCPeer to understand a different protocol.
281      * If you reimplement it, be sure to remove the processed portion of the data from the reference parameter.
282      * Return "qMakePair(QString(), QList<QVariant>())" if the deserialized data doesn't invoke a signal.
283      * Return "qMakePair(QString(), QList<QVariant>() << QVariant())" if the protocol has been violated and
284      * the connection should be severed.
285      */
286     virtual QPair<QString, QList<QVariant> > deserialize(QByteArray& data);
287
288     /*!
289      * Indicates whether the data currently received from the network can be deserialized.
290      *
291      * The default behavior of this function returns true if the buffer contains a newline character.
292      *
293      * Reimplement this function in a subclass to allow QxtRPCPeer to understand a different protocol.
294      */
295     virtual bool canDeserialize(const QByteArray& buffer) const;
296
297
298
299     /*!
300      * is called in Server mode when a new connection is available. the default implementation returns a new QTCPSocket
301      * for the \p socketDescriptor
302      */
303     virtual QTcpSocket * incomingConnection ( int socketDescriptor );
304
305
306 private:
307     QXT_DECLARE_PRIVATE(QxtRPCPeer);
308
309 private slots:
310     void dataAvailable();
311     void disconnectSender();
312 };
313 #endif