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

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

1st compiling version with clusterENet.

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