summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-02-07 19:01:12 +0000
committerMike Buland <eichlan@xagasoft.com>2008-02-07 19:01:12 +0000
commit9ab87f39d7fc37e52d742d38b191eed9128d4b5b (patch)
tree17a00529eda3d9a5a979c05d688f219f7af1631a
parent5574841cc88412854b2cb94253152b3606803e2a (diff)
downloadlibbu++-9ab87f39d7fc37e52d742d38b191eed9128d4b5b.tar.gz
libbu++-9ab87f39d7fc37e52d742d38b191eed9128d4b5b.tar.bz2
libbu++-9ab87f39d7fc37e52d742d38b191eed9128d4b5b.tar.xz
libbu++-9ab87f39d7fc37e52d742d38b191eed9128d4b5b.zip
Wowee, I think all this new stuff works, Conduit I don't need now, so it's not
done yet. The Client class now supports a function called getLink() which returns a ClientLink object. This object may then be passed off to any other class and called to send messages to that client object. It is threadsafe if ItoServer is being used, and not for Server. Sending a message via a ClientLink calls the onMessage function on the assosiated protocol. Note that sending messages from within protocol event handlers or functions they call, while safe, may be slow and it's reccomended that you avoid this.
-rw-r--r--src/client.cpp19
-rw-r--r--src/client.h8
-rw-r--r--src/clientlink.cpp17
-rw-r--r--src/clientlink.h25
-rw-r--r--src/clientlinkfactory.cpp17
-rw-r--r--src/clientlinkfactory.h26
-rw-r--r--src/conduit.cpp7
-rw-r--r--src/conduit.h26
-rw-r--r--src/itoserver.cpp67
-rw-r--r--src/itoserver.h34
-rw-r--r--src/protocol.cpp4
-rw-r--r--src/protocol.h3
-rw-r--r--src/server.cpp31
-rw-r--r--src/server.h24
-rw-r--r--src/socket.cpp4
-rw-r--r--src/socket.h1
16 files changed, 308 insertions, 5 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 1ef9151..d1eb29c 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -11,15 +11,18 @@
11#include <errno.h> 11#include <errno.h>
12#include "bu/exceptions.h" 12#include "bu/exceptions.h"
13#include "bu/protocol.h" 13#include "bu/protocol.h"
14#include "bu/clientlink.h"
15#include "bu/clientlinkfactory.h"
14 16
15/** Read buffer size. */ 17/** Read buffer size. */
16#define RBS (1024*2) 18#define RBS (1024*2)
17 19
18Bu::Client::Client( Bu::Socket *pSocket ) : 20Bu::Client::Client( Bu::Socket *pSocket, class Bu::ClientLinkFactory *pfLink ) :
19 pSocket( pSocket ), 21 pSocket( pSocket ),
20 pProto( NULL ), 22 pProto( NULL ),
21 nRBOffset( 0 ), 23 nRBOffset( 0 ),
22 bWantsDisconnect( false ) 24 bWantsDisconnect( false ),
25 pfLink( pfLink )
23{ 26{
24} 27}
25 28
@@ -233,3 +236,15 @@ void Bu::Client::close()
233{ 236{
234 pSocket->close(); 237 pSocket->close();
235} 238}
239
240Bu::ClientLink *Bu::Client::getLink()
241{
242 return pfLink->createLink( this );
243}
244
245void Bu::Client::onMessage( const Bu::FString &sMsg )
246{
247 if( pProto )
248 pProto->onMessage( this, sMsg );
249}
250
diff --git a/src/client.h b/src/client.h
index 3764375..20eb8b8 100644
--- a/src/client.h
+++ b/src/client.h
@@ -16,6 +16,7 @@ namespace Bu
16{ 16{
17 class Protocol; 17 class Protocol;
18 class Socket; 18 class Socket;
19 class ClientLinkFactory;
19 20
20 /** 21 /**
21 *@author Mike Buland 22 *@author Mike Buland
@@ -24,7 +25,7 @@ namespace Bu
24 class Client 25 class Client
25 { 26 {
26 public: 27 public:
27 Client( Bu::Socket *pSocket ); 28 Client( Bu::Socket *pSocket, Bu::ClientLinkFactory *pfLink );
28 virtual ~Client(); 29 virtual ~Client();
29 30
30 void processInput(); 31 void processInput();
@@ -59,6 +60,10 @@ namespace Bu
59 void disconnect(); 60 void disconnect();
60 bool wantsDisconnect(); 61 bool wantsDisconnect();
61 62
63 class ClientLink *getLink();
64
65 void onMessage( const Bu::FString &sMsg );
66
62 private: 67 private:
63 Bu::Socket *pSocket; 68 Bu::Socket *pSocket;
64 Bu::Protocol *pProto; 69 Bu::Protocol *pProto;
@@ -66,6 +71,7 @@ namespace Bu
66 int nRBOffset; 71 int nRBOffset;
67 Bu::FString sWriteBuf; 72 Bu::FString sWriteBuf;
68 bool bWantsDisconnect; 73 bool bWantsDisconnect;
74 class Bu::ClientLinkFactory *pfLink;
69 }; 75 };
70} 76}
71 77
diff --git a/src/clientlink.cpp b/src/clientlink.cpp
new file mode 100644
index 0000000..7061a71
--- /dev/null
+++ b/src/clientlink.cpp
@@ -0,0 +1,17 @@
1/*
2 * Copyright (C) 2007 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/clientlink.h"
9
10Bu::ClientLink::ClientLink()
11{
12}
13
14Bu::ClientLink::~ClientLink()
15{
16}
17
diff --git a/src/clientlink.h b/src/clientlink.h
new file mode 100644
index 0000000..e76665b
--- /dev/null
+++ b/src/clientlink.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2007 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CLIENT_LINK_H
9#define BU_CLIENT_LINK_H
10
11#include "bu/fstring.h"
12
13namespace Bu
14{
15 class ClientLink
16 {
17 public:
18 ClientLink();
19 virtual ~ClientLink();
20
21 virtual void sendMsg( const Bu::FString &sMsg )=0;
22 };
23};
24
25#endif
diff --git a/src/clientlinkfactory.cpp b/src/clientlinkfactory.cpp
new file mode 100644
index 0000000..523d8ec
--- /dev/null
+++ b/src/clientlinkfactory.cpp
@@ -0,0 +1,17 @@
1/*
2 * Copyright (C) 2007 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "clientlinkfactory.h"
9
10Bu::ClientLinkFactory::ClientLinkFactory()
11{
12}
13
14Bu::ClientLinkFactory::~ClientLinkFactory()
15{
16}
17
diff --git a/src/clientlinkfactory.h b/src/clientlinkfactory.h
new file mode 100644
index 0000000..4d3ed7b
--- /dev/null
+++ b/src/clientlinkfactory.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2007 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CLIENT_LINK_FACTORY_H
9#define BU_CLIENT_LINK_FACTORY_H
10
11namespace Bu
12{
13 class Client;
14 class ClientLink;
15
16 class ClientLinkFactory
17 {
18 public:
19 ClientLinkFactory();
20 virtual ~ClientLinkFactory();
21
22 virtual Bu::ClientLink *createLink( Bu::Client *pClient )=0;
23 };
24};
25
26#endif
diff --git a/src/conduit.cpp b/src/conduit.cpp
new file mode 100644
index 0000000..413bf7c
--- /dev/null
+++ b/src/conduit.cpp
@@ -0,0 +1,7 @@
1/*
2 * Copyright (C) 2007 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
diff --git a/src/conduit.h b/src/conduit.h
new file mode 100644
index 0000000..4598bd1
--- /dev/null
+++ b/src/conduit.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2007 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CONDUIT_H
9#define BU_CONDUIT_H
10
11#include "bu/stream.h"
12#include "bu/fstring.h"
13
14namespace Bu
15{
16 /**
17 * Simple inter-thread communication stream. This acts like a pair of
18 * pipes for stream communication between any two things, but without the
19 * use of pipes, making this a bad choice for IPC.
20 */
21 class Conduit : public Stream
22 {
23 };
24}
25
26#endif
diff --git a/src/itoserver.cpp b/src/itoserver.cpp
index 7426e8a..db5ae04 100644
--- a/src/itoserver.cpp
+++ b/src/itoserver.cpp
@@ -127,7 +127,8 @@ Bu::ItoServer::ItoClient::ItoClient( ItoServer &rSrv, int iSocket, int iPort,
127 FD_SET( iSocket, &fdActive ); 127 FD_SET( iSocket, &fdActive );
128 128
129 pClient = new Client( 129 pClient = new Client(
130 new Bu::Socket( iSocket ) 130 new Bu::Socket( iSocket ),
131 new SrvClientLinkFactory( rSrv )
131 ); 132 );
132} 133}
133 134
@@ -137,7 +138,10 @@ Bu::ItoServer::ItoClient::~ItoClient()
137 138
138void *Bu::ItoServer::ItoClient::run() 139void *Bu::ItoServer::ItoClient::run()
139{ 140{
141 imProto.lock();
140 rSrv.onNewConnection( pClient, iPort ); 142 rSrv.onNewConnection( pClient, iPort );
143 pClient->processOutput();
144 imProto.unlock();
141 145
142 for(;;) 146 for(;;)
143 { 147 {
@@ -151,14 +155,29 @@ void *Bu::ItoServer::ItoClient::run()
151 throw ExceptionBase("Error attempting to scan open connections."); 155 throw ExceptionBase("Error attempting to scan open connections.");
152 } 156 }
153 157
158 while( !qMsg.isEmpty() )
159 {
160 imProto.lock();
161 Bu::FString *pMsg = qMsg.dequeue();
162 pClient->onMessage( *pMsg );
163 delete pMsg;
164 pClient->processOutput();
165 imProto.unlock();
166 }
167
154 if( FD_ISSET( iSocket, &fdRead ) ) 168 if( FD_ISSET( iSocket, &fdRead ) )
155 { 169 {
170 imProto.lock();
156 pClient->processInput(); 171 pClient->processInput();
172 imProto.unlock();
157 if( !pClient->isOpen() ) 173 if( !pClient->isOpen() )
158 { 174 {
175 imProto.lock();
159 rSrv.onClosedConnection( pClient ); 176 rSrv.onClosedConnection( pClient );
177 imProto.unlock();
160 178
161 rSrv.clientCleanup( iSocket ); 179 rSrv.clientCleanup( iSocket );
180
162 return NULL; 181 return NULL;
163 } 182 }
164 } 183 }
@@ -166,9 +185,55 @@ void *Bu::ItoServer::ItoClient::run()
166 // Now we just try to write all the pending data on the socket. 185 // Now we just try to write all the pending data on the socket.
167 // this could be done better eventually, if we care about the socket 186 // this could be done better eventually, if we care about the socket
168 // wanting to accept writes (using a select). 187 // wanting to accept writes (using a select).
188 imProto.lock();
169 pClient->processOutput(); 189 pClient->processOutput();
190 imProto.unlock();
170 } 191 }
171 192
172 return NULL; 193 return NULL;
173} 194}
174 195
196Bu::ItoServer::SrvClientLink::SrvClientLink( ItoClient *pClient ) :
197 pClient( pClient )
198{
199}
200
201Bu::ItoServer::SrvClientLink::~SrvClientLink()
202{
203}
204
205void Bu::ItoServer::SrvClientLink::sendMsg( const Bu::FString &sMsg )
206{
207 if( !pClient->imProto.trylock() )
208 {
209 pClient->pClient->onMessage( sMsg );
210 pClient->pClient->processOutput();
211 pClient->imProto.unlock();
212 }
213 else
214 {
215 Bu::FString *pMsg = new Bu::FString( sMsg );
216 pClient->qMsg.enqueue( pMsg );
217 }
218}
219
220Bu::ItoServer::SrvClientLinkFactory::SrvClientLinkFactory(
221 Bu::ItoServer &rSrv ) :
222 rSrv( rSrv )
223{
224}
225
226Bu::ItoServer::SrvClientLinkFactory::~SrvClientLinkFactory()
227{
228}
229
230Bu::ClientLink *Bu::ItoServer::SrvClientLinkFactory::createLink(
231 Bu::Client *pClient )
232{
233 rSrv.imClients.lock();
234 ItoClient *pCli = rSrv.hClients.get( *pClient->getSocket() );
235 rSrv.imClients.unlock();
236
237 return new SrvClientLink( pCli );
238}
239
diff --git a/src/itoserver.h b/src/itoserver.h
index f11960c..09ed1cd 100644
--- a/src/itoserver.h
+++ b/src/itoserver.h
@@ -17,6 +17,9 @@
17#include "bu/itoqueue.h" 17#include "bu/itoqueue.h"
18#include "bu/set.h" 18#include "bu/set.h"
19 19
20#include "bu/clientlink.h"
21#include "bu/clientlinkfactory.h"
22
20namespace Bu 23namespace Bu
21{ 24{
22 class ServerSocket; 25 class ServerSocket;
@@ -47,6 +50,7 @@ namespace Bu
47 class ItoServer : public Ito 50 class ItoServer : public Ito
48 { 51 {
49 friend class ItoClient; 52 friend class ItoClient;
53 friend class SrvClientLinkFactory;
50 public: 54 public:
51 ItoServer(); 55 ItoServer();
52 virtual ~ItoServer(); 56 virtual ~ItoServer();
@@ -65,8 +69,10 @@ namespace Bu
65 virtual void *run(); 69 virtual void *run();
66 70
67 private: 71 private:
72 class SrvClientLink;
68 class ItoClient : public Ito 73 class ItoClient : public Ito
69 { 74 {
75 friend class Bu::ItoServer::SrvClientLink;
70 public: 76 public:
71 ItoClient( ItoServer &rSrv, int nSocket, int nPort, 77 ItoClient( ItoServer &rSrv, int nSocket, int nPort,
72 int nTimeoutSec, int nTimeoutUSec ); 78 int nTimeoutSec, int nTimeoutUSec );
@@ -74,6 +80,9 @@ namespace Bu
74 80
75 virtual void *run(); 81 virtual void *run();
76 82
83 typedef ItoQueue<Bu::FString *> StringQueue;
84 StringQueue qMsg;
85
77 private: 86 private:
78 ItoServer &rSrv; 87 ItoServer &rSrv;
79 Client *pClient; 88 Client *pClient;
@@ -82,6 +91,31 @@ namespace Bu
82 int iPort; 91 int iPort;
83 int nTimeoutSec; 92 int nTimeoutSec;
84 int nTimeoutUSec; 93 int nTimeoutUSec;
94 ItoMutex imProto;
95 };
96
97 class SrvClientLink : public Bu::ClientLink
98 {
99 public:
100 SrvClientLink( ItoClient *pClient );
101 virtual ~SrvClientLink();
102
103 virtual void sendMsg( const Bu::FString &sMsg );
104
105 private:
106 ItoClient *pClient;
107 };
108
109 class SrvClientLinkFactory : public Bu::ClientLinkFactory
110 {
111 public:
112 SrvClientLinkFactory( ItoServer &rSrv );
113 virtual ~SrvClientLinkFactory();
114
115 virtual Bu::ClientLink *createLink( Bu::Client *pClient );
116
117 private:
118 ItoServer &rSrv;
85 }; 119 };
86 120
87 int nTimeoutSec; 121 int nTimeoutSec;
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 7a59586..e197b7f 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -17,3 +17,7 @@ Bu::Protocol::~Protocol()
17{ 17{
18} 18}
19 19
20void Bu::Protocol::onMessage( Bu::Client *pClient, const Bu::FString &sMsg )
21{
22}
23
diff --git a/src/protocol.h b/src/protocol.h
index c557512..61fff93 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -10,6 +10,8 @@
10 10
11#include <stdint.h> 11#include <stdint.h>
12 12
13#include "bu/fstring.h"
14
13namespace Bu 15namespace Bu
14{ 16{
15 class Client; 17 class Client;
@@ -26,6 +28,7 @@ namespace Bu
26 28
27 virtual void onNewConnection( Bu::Client *pClient )=0; 29 virtual void onNewConnection( Bu::Client *pClient )=0;
28 virtual void onNewData( Bu::Client *pClient )=0; 30 virtual void onNewData( Bu::Client *pClient )=0;
31 virtual void onMessage( Bu::Client *pClient, const Bu::FString &sMsg );
29 32
30 private: 33 private:
31 34
diff --git a/src/server.cpp b/src/server.cpp
index 861e2e3..cca486a 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -109,10 +109,39 @@ void Bu::Server::addClient( int nSocket, int nPort )
109 FD_SET( nSocket, &fdActive ); 109 FD_SET( nSocket, &fdActive );
110 110
111 Client *c = new Client( 111 Client *c = new Client(
112 new Bu::Socket( nSocket ) 112 new Bu::Socket( nSocket ),
113 new SrvClientLinkFactory()
113 ); 114 );
114 hClients.insert( nSocket, c ); 115 hClients.insert( nSocket, c );
115 116
116 onNewConnection( c, nPort ); 117 onNewConnection( c, nPort );
117} 118}
118 119
120Bu::Server::SrvClientLink::SrvClientLink( Bu::Client *pClient ) :
121 pClient( pClient )
122{
123}
124
125Bu::Server::SrvClientLink::~SrvClientLink()
126{
127}
128
129void Bu::Server::SrvClientLink::sendMsg( const Bu::FString &sMsg )
130{
131 pClient->onMessage( sMsg );
132}
133
134Bu::Server::SrvClientLinkFactory::SrvClientLinkFactory()
135{
136}
137
138Bu::Server::SrvClientLinkFactory::~SrvClientLinkFactory()
139{
140}
141
142Bu::ClientLink *Bu::Server::SrvClientLinkFactory::createLink(
143 Bu::Client *pClient )
144{
145 return new SrvClientLink( pClient );
146}
147
diff --git a/src/server.h b/src/server.h
index 02f3546..1ba5fd7 100644
--- a/src/server.h
+++ b/src/server.h
@@ -13,6 +13,9 @@
13#include "bu/fstring.h" 13#include "bu/fstring.h"
14#include "bu/list.h" 14#include "bu/list.h"
15 15
16#include "bu/clientlink.h"
17#include "bu/clientlinkfactory.h"
18
16namespace Bu 19namespace Bu
17{ 20{
18 class ServerSocket; 21 class ServerSocket;
@@ -58,6 +61,27 @@ namespace Bu
58 virtual void onClosedConnection( Client *pClient )=0; 61 virtual void onClosedConnection( Client *pClient )=0;
59 62
60 private: 63 private:
64 class SrvClientLink : public Bu::ClientLink
65 {
66 public:
67 SrvClientLink( Bu::Client *pClient );
68 virtual ~SrvClientLink();
69
70 virtual void sendMsg( const Bu::FString &sMsg );
71
72 private:
73 Bu::Client *pClient;
74 };
75
76 class SrvClientLinkFactory : public Bu::ClientLinkFactory
77 {
78 public:
79 SrvClientLinkFactory();
80 virtual ~SrvClientLinkFactory();
81
82 virtual Bu::ClientLink *createLink( Bu::Client *pClient );
83 };
84
61 int nTimeoutSec; 85 int nTimeoutSec;
62 int nTimeoutUSec; 86 int nTimeoutUSec;
63 fd_set fdActive; 87 fd_set fdActive;
diff --git a/src/socket.cpp b/src/socket.cpp
index 7b55c4b..94639b1 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -364,3 +364,7 @@ Bu::FString Bu::Socket::getAddress() const
364 return sAddress; 364 return sAddress;
365} 365}
366 366
367Bu::Socket::operator int() const
368{
369 return nSocket;
370}
diff --git a/src/socket.h b/src/socket.h
index eee0be3..7acf055 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -57,6 +57,7 @@ namespace Bu
57 virtual void setBlocking( bool bBlocking=true ); 57 virtual void setBlocking( bool bBlocking=true );
58 58
59 Bu::FString getAddress() const; 59 Bu::FString getAddress() const;
60 operator int() const;
60 61
61 private: 62 private:
62 void setAddress(); 63 void setAddress();