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

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