source: osgVisual/src/cluster/dataIO_clusterENet_implementation.cpp @ 66

Last change on this file since 66 was 66, checked in by Torben Dannhauer, 14 years ago

ENet debugging/improvements

File size: 9.0 KB
Line 
1#include "dataIO_clusterENet_implementation.h"
2
3using namespace osgVisual;
4
5int dataIO_clusterENet_implementation::activeENetInstances = 0;
6
7dataIO_clusterENet_implementation::dataIO_clusterENet_implementation()
8{
9        std::cout << "Instantiated server class# "<< activeENetInstances << std::endl;
10        serverInitialized = false;
11        // Start ENet
12        if (activeENetInstances++ == 0)
13        {
14                if( enet_initialize() != 0)
15                {
16                        std::cout <<  "An error occurred while initializing ENet." << std::endl;
17                }
18                else
19                {
20                        std::cout << "Starting ENet subsystem successful" << std::endl;
21                }
22        }
23}
24
25dataIO_clusterENet_implementation::~dataIO_clusterENet_implementation()
26{
27        // Delete Host Object
28        enet_host_destroy(host);
29
30        // Stop ENet if it is the last element.
31        if(--activeENetInstances == 0)
32        {
33                std::cout << "Close ENet subsystem" << std::endl;
34                enet_deinitialize();
35        }
36        std::cout << "Destroyed server class# "<< activeENetInstances << std::endl;
37}
38
39bool dataIO_clusterENet_implementation::init(dataIO_clusterENet_implementation::role role_, unsigned short port_, int maxClients_, int maxChannels_, int maxInBandwidth_, int maxOutBandwidth_)
40{
41        port = port_;
42        currentRole = role_;
43
44        if(currentRole == dataIO_clusterENet_implementation::SERVER)
45        {
46                /* Bind the server to the default localhost.     */
47                /* A specific host address can be specified by   */
48                /* enet_address_set_host (& address, "x.x.x.x"); */
49
50                address.host = ENET_HOST_ANY;
51                /* Bind the server to port. */
52                address.port = port;
53
54                host = enet_host_create (& address /* the address to bind the server host to */, 
55                                                                         maxClients_      /* allow up to 32 clients and/or outgoing connections */,
56                                                                         maxChannels_      /* allow up to 2 channels to be used, 0 and 1 */,
57                                                                         maxInBandwidth_      /* assume any amount of incoming bandwidth */,
58                                                                         maxOutBandwidth_      /* assume any amount of outgoing bandwidth */);
59                if (host == NULL)
60                {
61                        std::cout <<  "An error occurred while trying to create an ENet server." << std::endl;
62                        return false;
63                }
64        }       // IF SERVER END
65
66        if(currentRole == dataIO_clusterENet_implementation::CLIENT)
67        {
68                 host = enet_host_create (NULL /* create a client host */,
69                                                                         maxClients_      /* allow up to 32 clients and/or outgoing connections */,
70                                                                         maxChannels_      /* allow up to 2 channels to be used, 0 and 1 */,
71                                                                         maxInBandwidth_      /* assume any amount of incoming bandwidth */,
72                                                                         maxOutBandwidth_      /* assume any amount of outgoing bandwidth */);
73                 if (host == NULL)
74                {
75                        std::cout <<  "An error occurred while trying to create an ENet client." << std::endl;
76                        return false;
77                }
78
79        }       // IF CLIENT END
80
81        serverInitialized = true;
82        return true;
83}
84
85void dataIO_clusterENet_implementation::processEvents(int timeout_ms_)
86{
87        if(!serverInitialized)
88                return;
89
90        ENetEvent event;
91        while(enet_host_service (host, & event, timeout_ms_) > 0)
92        {
93                switch (event.type)
94                {
95                        case ENET_EVENT_TYPE_CONNECT:
96                                onConnect(&event);
97                                break;
98
99                        case ENET_EVENT_TYPE_RECEIVE:
100                                onReceivePacket(&event);
101                       
102                                /* Clean up the packet now that we're done using it. */
103                                enet_packet_destroy (event.packet);
104                                break;
105
106                        case ENET_EVENT_TYPE_DISCONNECT:
107                                onDisconnect(&event);
108                                break;
109                       
110                        case ENET_EVENT_TYPE_NONE:
111                                // nothing to do
112                                break;
113
114                        default: 
115                                std::cout << "Unknown Eventtype" << std::endl;
116                }       // SWITCH CASE END
117        }       // WHILE EVENT END
118
119}
120
121void dataIO_clusterENet_implementation::sendPacket( ENetPacket* packet_, enet_uint8 channelID_, unsigned int peerID_, bool autoFlush_ )
122{
123        // are connected peers available?
124        if( peerList.size() == 0 )
125        {
126                std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: No connected peer available!" << std::endl;
127                return;
128        }
129
130        // Client
131        if(currentRole == dataIO_clusterENet_implementation::CLIENT)
132        {
133                enet_peer_send (peerList[0], channelID_, packet_);
134        }
135
136        // Server
137        if(currentRole == dataIO_clusterENet_implementation::SERVER)
138        {
139                if(peerID_ < peerList.size())
140                        enet_peer_send (peerList[peerID_], channelID_, packet_);
141                else
142                        std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: Peer #"<<peerID_<<" is not available, only peers 0-"<<(peerList.size()-1)<<" are connected!" << std::endl;
143        }
144
145        if(autoFlush_)
146                enet_host_flush( host );
147}
148
149void dataIO_clusterENet_implementation::sendPacket( ENetPacket* packet_, enet_uint8 channelID_, std::string peerName_, bool autoFlush_ )
150{
151                // are connected peers available?
152        if( peerList.size() == 0 )
153        {
154                std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: No connected peer available!" << std::endl;
155                return;
156        }
157
158        // Client
159        if(currentRole == dataIO_clusterENet_implementation::CLIENT)
160        {
161                enet_peer_send (peerList[0], channelID_, packet_);
162        }
163
164        // Server
165        if(currentRole == dataIO_clusterENet_implementation::SERVER)
166        {
167                int peerID_=-1;
168                for(unsigned int i=0;i<peerList.size();i++)     // Search peer
169                {
170                        if( *((std::string*)peerList[i]->data) == peerName_ )
171                        {
172                                peerID_ = i;
173                                break;
174                        }
175                }
176                if( peerID_ >= 0 && peerID_ < (int)peerList.size())
177                        enet_peer_send (peerList[peerID_], channelID_, packet_);
178                else
179                        std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: Peer #"<<peerID_<<" is not available, only peers 0-"<<(peerList.size()-1)<<" are connected!" << std::endl;
180        }
181
182        if(autoFlush_)
183                enet_host_flush( host );
184}
185
186void dataIO_clusterENet_implementation::broadcastPacket( enet_uint8 channelID_, ENetPacket* packet_, bool autoFlush_ )
187{
188        if(currentRole != dataIO_clusterENet_implementation::SERVER)
189                return;
190
191        enet_host_broadcast( host, channelID_, packet_ );
192        if(autoFlush_)
193                enet_host_flush( host );
194}
195
196bool dataIO_clusterENet_implementation::connectTo( const char* remoteAddr_, int connectTimeout_ms_, int clientInfo_,  int channelToAlloc_ )
197{
198        if(currentRole != dataIO_clusterENet_implementation::CLIENT)
199                return false;
200
201        ENetAddress address;
202        enet_address_set_host (& address, remoteAddr_);
203    address.port = port;
204
205       
206        ENetPeer* tmpPeer = enet_host_connect( host, &address, channelToAlloc_, clientInfo_ );    // host, remote address, number of channels, describing data.
207   
208    if (tmpPeer == NULL)
209    {
210                std::cout << "No available peers for initiating an ENet connection." << std::endl;
211       return false;
212    }
213   
214    /* Wait up to 5 seconds for the connection attempt to succeed. */
215    if (enet_host_service (host, & event, connectTimeout_ms_) > 0
216                && event.type == ENET_EVENT_TYPE_CONNECT)
217    {
218                peerList.push_back( tmpPeer );
219                std::cout << "Connection to " << remoteAddr_ << ":"<<port<<" succeeded." << std::endl;
220                // Note down peers remote IP.
221                char *hostIP = new char[20];
222                enet_address_get_host_ip( &address, hostIP, 20 );
223                tmpPeer->data = hostIP;
224
225                return true;
226    }
227    else
228    {
229        /* Either the n seconds are up or a disconnect event was */
230        /* received. Reset the peer in the event the n seconds   */
231        /* had run out without any significant event.            */
232        enet_peer_reset (tmpPeer);
233
234                std::cout << "Connection to " << remoteAddr_ << ":"<<port<<" failed." << std::endl;
235                return false;
236    }
237}
238
239void dataIO_clusterENet_implementation::onReceivePacket(ENetEvent* event_)
240{
241                std::string datastring;
242                datastring.assign((char*)(event_->packet->data), event_->packet->dataLength);   
243                std::cout << "A packet of length "<<event_->packet->dataLength<<" containing "<<datastring<<" was received from "<<datastring<<" on channel "<<(int)(event_->channelID)<<std::endl;
244                datastring+=std::string("answer");
245
246                ENetPacket * packet = enet_packet_create (datastring.c_str(), 
247                                                                                                  datastring.size(), 
248                                                                                                  ENET_PACKET_FLAG_RELIABLE);
249               
250                // Send answer
251                sendPacket( packet, 0, 0, true);
252}
253
254void dataIO_clusterENet_implementation::onConnect(ENetEvent* event_)
255{
256        /* Get connect remote IP */
257        char *hostIP = new char[20];
258        enet_address_get_host_ip(&(event_->peer->address), hostIP, 20);
259
260        /* debug output */
261        std::cout << "A new client connected from "<<hostIP<<"." << std::endl; 
262               
263        /* Store any relevant client information here. */
264        event_->peer ->data = hostIP;   
265
266        /* note peer for duplex usage of the connection */
267        peerList.push_back(event_->peer);       
268}
269
270void dataIO_clusterENet_implementation::onDisconnect(ENetEvent* event_)
271{
272        // remove peer pionter from peerList
273        int foundOn = -1;
274        for(unsigned int i=0;i<peerList.size();i++)
275        {
276                if(peerList[0] == event_->peer)
277                {
278                        peerList.erase(peerList.begin()+i);
279                        break;
280                }
281        }
282
283
284        if(currentRole == dataIO_clusterENet_implementation::SERVER)
285        {
286                std::cout << "Client " << (char*)event_->peer->data << " disconnected." << std::endl;
287
288                /* Reset the peer's client information. */
289                delete event_->peer->data;
290                event_->peer->data = NULL;
291        }
292
293        if(currentRole == dataIO_clusterENet_implementation::CLIENT)
294        {
295                std::cout << "Server "<< (char*)event_->peer->data<<"disconnected." << std::endl;
296
297                // Reset the server information
298                delete event_->peer->data;
299                event_->peer->data = NULL;
300        }
301}
Note: See TracBrowser for help on using the repository browser.