#include <OSGClusterServer.h>
Public Member Functions | |
Constructors | |
| * | ClusterServer (WindowPtr window, const std::string &serviceName, const std::string &connectionType="StreamSock", const std::string &address="", UInt32 servicePort=8437, const std::string &serviceGroup="") |
Destructor | |
| *virtual | ~ClusterServer (void) |
server actions | |
| *void | start (void) |
| void | stop (void) |
| void | render (RenderActionBase *action) |
| void | doSync (bool applyToChangelist) |
| void | doRender (RenderActionBase *action) |
| void | doSwap (void) |
window access | |
| *WindowPtr | getClusterWindow (void) |
| WindowPtr | getServerWindow (void) |
| RemoteAspect * | getRemoteAspect (void) const |
set | |
| *void | setInterface (const std::string &interf) |
Protected Member Functions | |
ClusterWindow changed function | |
| *bool | windowChanged (FieldContainerPtr &fcp, RemoteAspect *) |
Protected Attributes | |
Member | |
| *WindowPtr | _window |
| PointConnection * | _connection |
| std::string | _requestAddress |
| std::string | _boundAddress |
| ClusterWindowPtr | _clusterWindow |
| RemoteAspect * | _aspect |
| std::string | _serviceName |
| std::string | _connectionType |
| UInt32 | _servicePort |
| std::string | _serviceGroup |
| UInt32 | _serverId |
| std::string | _interface |
Private Member Functions | |
| ClusterServer (const ClusterServer &source) | |
| prohibit default function (move to 'public' if needed) | |
| void | operator= (const ClusterServer &source) |
| prohibit default function (move to 'public' if needed) | |
helper function | |
| *void | acceptClient () |
// create a server GLUTWindowPtr window=GLUTWindowcreate(); server = new ClusterServer(window,"server1","Multicast"); // wait for clients to connect server->init(); ... // render server->render(ract);
Definition at line 59 of file OSGClusterServer.h.
|
||||||||||||||||||||||||||||
|
Constructor
Definition at line 88 of file OSGClusterServer.cpp. References _requestAddress, and _serviceName. 00093 : 00094 _window(window), 00095 _connection(NULL), 00096 _requestAddress(address), 00097 _boundAddress(""), 00098 _clusterWindow(), 00099 _aspect(NULL), 00100 _serviceName(serviceName), 00101 _connectionType(connectionType), 00102 _servicePort(servicePort), 00103 _serviceGroup(serviceGroup), 00104 _serverId(0), 00105 _interface("") 00106 { 00107 char localhost[256]; 00108 00109 // default is hostname 00110 if(_serviceName.empty()) 00111 { 00112 gethostname(localhost,255); 00113 _serviceName = localhost; 00114 } 00115 // if service contains ":" than treat as address 00116 if(_requestAddress.empty()) 00117 { 00118 if(strstr(_serviceName.c_str(),":")) 00119 _requestAddress = _serviceName; 00120 } 00121 }
|
|
|
Destructor. Disconnect from all connected rendering servers Definition at line 128 of file OSGClusterServer.cpp. References _aspect, and _connection. 00129 { 00130 try 00131 { 00132 if(_connection) 00133 delete _connection; 00134 if(_aspect) 00135 delete _aspect; 00136 } 00137 catch(...) 00138 { 00139 } 00140 }
|
|
|
|
|
|
start server Start cluster server and wait for a client to connect. This method will return after a client connection or an error situation. Definition at line 151 of file OSGClusterServer.cpp. References _aspect, _connection, acceptClient(), osg::BinaryDataHandler::flush(), osg::ClusterWindowBase::getClassType(), osg::BinaryDataHandler::getValue(), osg::osgTypedMethodFunctor2ObjPtrCPtrRef(), osg::BinaryDataHandler::putValue(), osg::RemoteAspect::registerChanged(), osg::Connection::selectChannel(), osg::BinaryDataHandler::setNetworkOrder(), and windowChanged(). 00152 { 00153 OSG::FieldContainerType *fct; 00154 00155 // reset conneciton 00156 if(_connection) 00157 delete _connection; 00158 _connection = NULL; 00159 00160 // create aspect 00161 _aspect = new RemoteAspect(); 00162 00163 // register interrest for all changed cluster windows 00164 for(UInt32 i = 0; i < OSG::TypeFactory::the()->getNumTypes(); ++i) 00165 { 00166 fct=OSG::FieldContainerFactory::the()->findType(i); 00167 if(fct && fct->isDerivedFrom(ClusterWindow::getClassType())) 00168 { 00169 _aspect->registerChanged( 00170 *fct, 00171 osgTypedMethodFunctor2ObjPtrCPtrRef 00172 < 00173 bool, 00174 ClusterServer, 00175 FieldContainerPtr, 00176 RemoteAspect * 00177 >(this,&ClusterServer::windowChanged)); 00178 } 00179 } 00180 // accept incomming connections 00181 try { 00182 UInt8 forceNetworkOrder; 00183 #if BYTE_ORDER == LITTLE_ENDIAN 00184 UInt8 littleEndian = true; 00185 #else 00186 UInt8 littleEndian = false; 00187 #endif 00188 00189 // accept 00190 acceptClient(); 00191 // determine network order 00192 _connection->putValue(littleEndian); 00193 _connection->flush(); 00194 _connection->selectChannel(); 00195 _connection->getValue(forceNetworkOrder); 00196 _connection->setNetworkOrder((forceNetworkOrder != 0)); 00197 } 00198 catch(...) 00199 { 00200 throw; 00201 } 00202 }
|
|
|
Stop cluster server, remove current remote aspect and all its field containers. Definition at line 207 of file OSGClusterServer.cpp. References _aspect, _clusterWindow, _connection, and osg::NullFC. 00208 { 00209 // get aspect ownership 00210 if(_clusterWindow != NullFC) 00211 { 00212 _aspect=_clusterWindow->getNetwork()->getAspect(); 00213 _clusterWindow->getNetwork()->setAspect(NULL); 00214 } 00215 // destroy connection 00216 try 00217 { 00218 if(_connection) 00219 delete _connection; 00220 _connection = NULL; 00221 } 00222 catch(...) 00223 { 00224 } 00225 // destroy aspect 00226 if(_aspect) 00227 delete _aspect; 00228 // reset 00229 _connection=NULL; 00230 _aspect=NULL; 00231 _clusterWindow=NullFC; 00232 }
|
|
|
sync with client and render scenegraph Definition at line 236 of file OSGClusterServer.cpp. References doRender(), doSwap(), and doSync().
|
|
|
Synchronize all field containers with the client and call todo: Sync RenderAciton contents Definition at line 252 of file OSGClusterServer.cpp. References _aspect, _clusterWindow, _connection, _serverId, _serviceName, _window, osg::NullFC, osg::RemoteAspect::receiveSync(), osg::SHLChunk::setClusterId(), and SINFO. Referenced by render(). 00253 { 00254 // do we have a cluster window? 00255 if(_clusterWindow==NullFC) 00256 { 00257 do 00258 { 00259 // recive 00260 _aspect->receiveSync(*_connection,applyToChangelist); 00261 } 00262 while(_clusterWindow==NullFC); 00263 // get server id 00264 for(_serverId=0; 00265 _clusterWindow->getServers()[_serverId] != _serviceName && 00266 _serverId<_clusterWindow->getServers().size(); 00267 _serverId++); 00268 // server connected and cluster window found 00269 SINFO << "Start server " << _serviceName 00270 << " with id " << _serverId 00271 << std::endl; 00272 // now the window is responsible for connection and aspect 00273 _clusterWindow->getNetwork()->setMainConnection(_connection); 00274 _clusterWindow->getNetwork()->setAspect (_aspect); 00275 _connection=NULL; 00276 _aspect=NULL; 00277 SHLChunk::setClusterId(Int32(_serverId)); 00278 _clusterWindow->serverInit(_window,_serverId); 00279 } 00280 00281 RemoteAspect *aspect=_clusterWindow->getNetwork()->getAspect(); 00282 Connection *connection=_clusterWindow->getNetwork()->getMainConnection(); 00283 00284 // sync with render clinet 00285 aspect->receiveSync(*connection,applyToChangelist); 00286 00287 // sync with render client 00288 if(_clusterWindow->getInterleave()) 00289 { 00290 // if the reminder of the division of interleave and 00291 // framecount is equal to the servers id, the right 00292 // sync point for the current render frame is reached 00293 while( (_clusterWindow->getFrameCount()% 00294 _clusterWindow->getInterleave()) 00295 != 00296 (_serverId%_clusterWindow->getInterleave()) ) 00297 { 00298 aspect->receiveSync(*connection,applyToChangelist); 00299 } 00300 } 00301 }
|
|
|
render server window Definition at line 305 of file OSGClusterServer.cpp. References _clusterWindow, _serverId, and _window. Referenced by render(). 00306 { 00307 _clusterWindow->serverRender( _window,_serverId,action ); 00308 }
|
|
|
swap server window Definition at line 312 of file OSGClusterServer.cpp. References _clusterWindow, _serverId, and _window. Referenced by render(). 00313 { 00314 _clusterWindow->serverSwap ( _window,_serverId ); 00315 }
|
|
|
return the cluster window received from the client Definition at line 319 of file OSGClusterServer.cpp. References _clusterWindow. 00320 { 00321 return _clusterWindow; 00322 }
|
|
|
return the window used for rendering Definition at line 326 of file OSGClusterServer.cpp. References _window. 00327 { 00328 return _window; 00329 }
|
|
|
return the cluster window received from the client Definition at line 46 of file OSGClusterServer.inl. References _aspect. 00047 { 00048 return _aspect; 00049 }
|
|
|
Definition at line 52 of file OSGClusterServer.inl. References _interface. 00053 { 00054 _interface = interf; 00055 }
|
|
||||||||||||
|
clusterWindow changed callback. This is a callback functor. It is called for each change of a ClusterWindow. Definition at line 334 of file OSGClusterServer.cpp. References _clusterWindow, _serviceName, osg::AttachmentContainerPtr::dcast(), osg::NullFC, and SWARNING. Referenced by start(). 00336 { 00337 if(_clusterWindow != NullFC) 00338 return true; 00339 00340 ClusterWindowPtr window=ClusterWindowPtr::dcast(fcp); 00341 00342 if(window->getServers().size()) 00343 { 00344 if(window->getServers().find(_serviceName) == 00345 window->getServers().end()) 00346 { 00347 SWARNING << "wrong window" << std::endl; 00348 } 00349 else 00350 { 00351 _clusterWindow=window; 00352 } 00353 } 00354 return true; 00355 }
|
|
|
Wait for incomming clients. A client can send a request for a special connection type or it can try to connect it it knows the servers address. Definition at line 361 of file OSGClusterServer.cpp. References _boundAddress, _connection, _connectionType, _interface, _requestAddress, _serviceGroup, _serviceName, _servicePort, osg::PointConnection::acceptGroup(), osg::SocketAddress::ANY, osg::Socket::bind(), osg::Connection::bind(), osg::BinaryMessage::clear(), osg::DgramSocket::close(), osg::ConnectionType::getName(), osg::BinaryMessage::getString(), osg::PointConnection::getType(), osg::SocketAddress::isMulticast(), osg::DgramSocket::join(), osg::DgramSocket::open(), osg::BinaryMessage::putString(), osg::DgramSocket::recvFrom(), osg::DgramSocket::sendTo(), osg::Connection::setInterface(), osg::Socket::setReusePort(), SINFO, SWARNING, osg::ConnectionFactory::the(), and osg::Socket::waitReadable(). Referenced by start(). 00362 { 00363 BinaryMessage msg; 00364 DgramSocket serviceSock; 00365 SocketAddress addr; 00366 std::string service; 00367 std::string connectionType; 00368 UInt32 readable; 00369 bool connected=false; 00370 std::string address; 00371 bool bound = false; 00372 00373 SINFO << "Waiting for request of " 00374 << _serviceName 00375 << std::endl; 00376 00377 try 00378 { 00379 if(!_requestAddress.empty()) 00380 { 00381 // create connection 00382 _connection = ConnectionFactory::the(). 00383 createPoint(_connectionType); 00384 if(_connection) 00385 { 00386 // set interface 00387 _connection->setInterface(_interface); 00388 // bind connection 00389 try 00390 { 00391 // bind to requested address 00392 _boundAddress = _connection->bind(_requestAddress); 00393 bound = true; 00394 } 00395 catch(...) 00396 { 00397 SINFO << "Unable to bind, use name as symbolic service name" 00398 << std::endl; 00399 } 00400 } 00401 } 00402 serviceSock.open(); 00403 serviceSock.setReusePort(true); 00404 // join to multicast group 00405 if(!_serviceGroup.empty()) 00406 { 00407 SocketAddress groupAddress = SocketAddress( 00408 _serviceGroup.c_str(), 00409 _servicePort); 00410 if(groupAddress.isMulticast()) 00411 { 00412 SINFO << "wait for request on multicast:" << 00413 _serviceGroup << std::endl; 00414 serviceSock.bind(SocketAddress(SocketAddress::ANY, 00415 _servicePort)); 00416 serviceSock.join(SocketAddress(groupAddress)); 00417 } 00418 else 00419 { 00420 SINFO << "wait for request by broadcast:" << 00421 _serviceGroup << std::endl; 00422 serviceSock.bind(SocketAddress(groupAddress)); 00423 } 00424 } 00425 else 00426 { 00427 SINFO << "wait for request by broadcast" << std::endl; 00428 serviceSock.bind(SocketAddress(SocketAddress::ANY, 00429 _servicePort)); 00430 } 00431 00432 while(!connected) 00433 { 00434 try 00435 { 00436 if(_connection) 00437 readable = serviceSock.waitReadable(.01); 00438 else 00439 readable = true; 00440 if(readable) 00441 { 00442 serviceSock.recvFrom(msg,addr); 00443 00444 service = msg.getString(); 00445 connectionType = msg.getString(); 00446 00447 SINFO << "Request for " 00448 << service << " " 00449 << connectionType 00450 << std::endl; 00451 00452 if(service == _serviceName) 00453 { 00454 // remove old connection if typename missmaches 00455 if(_connection && 00456 _connection->getType()->getName() != connectionType) 00457 { 00458 delete _connection; 00459 _connection = NULL; 00460 } 00461 // try to create connection 00462 if(!_connection) 00463 { 00464 // create connection 00465 _connection = ConnectionFactory::the(). 00466 createPoint(connectionType); 00467 if(_connection) 00468 { 00469 // set interface 00470 _connection->setInterface(_interface); 00471 // bind connection 00472 _boundAddress = _connection->bind(_requestAddress); 00473 bound = true; 00474 } 00475 else 00476 { 00477 SINFO << "Unknown connection type '" 00478 << connectionType << "'" << std::endl; 00479 } 00480 } 00481 if(_connection) 00482 { 00483 msg.clear ( ); 00484 msg.putString(_serviceName ); 00485 msg.putString(_boundAddress); 00486 serviceSock.sendTo(msg, addr); 00487 SINFO << "Response " 00488 << connectionType << ":" 00489 << _boundAddress 00490 << std::endl; 00491 } 00492 } 00493 } 00494 } 00495 catch(SocketConnReset &e) 00496 { 00497 // ignore if there is a connection. This can happen, if 00498 // a client has send a request. The server has send an 00499 // answer meanwile the client has send a second request 00500 // the client gets the answer to the first request and 00501 // the server tries to send a second answer. The second 00502 // answer can not be delivered because the client has 00503 // closed its service port. This is a win-socket problem. 00504 00505 SWARNING << e.what() << std::endl; 00506 00507 // if there is no connection, then its a real problem 00508 if(!_connection) 00509 throw; 00510 } 00511 catch(OSG_STDEXCEPTION_NAMESPACE::exception &e) 00512 { 00513 SWARNING << e.what() << std::endl; 00514 } 00515 try 00516 { 00517 // try to accept 00518 if(bound && _connection && _connection->acceptGroup(0.2) >= 0) 00519 { 00520 connected = true; 00521 SINFO << "Connection accepted " << _boundAddress << std::endl; 00522 } 00523 } 00524 catch(OSG_STDEXCEPTION_NAMESPACE::exception &e) 00525 { 00526 SWARNING << e.what() << std::endl; 00527 } 00528 } 00529 serviceSock.close(); 00530 } 00531 catch(OSG_STDEXCEPTION_NAMESPACE::exception &e) 00532 { 00533 throw; 00534 } 00535 }
|
|
|
|
|
|
Definition at line 127 of file OSGClusterServer.h. Referenced by doRender(), doSwap(), doSync(), and getServerWindow(). |
|
|
Definition at line 128 of file OSGClusterServer.h. Referenced by acceptClient(), doSync(), start(), stop(), and ~ClusterServer(). |
|
|
Definition at line 129 of file OSGClusterServer.h. Referenced by acceptClient(), and ClusterServer(). |
|
|
Definition at line 130 of file OSGClusterServer.h. Referenced by acceptClient(). |
|
|
Definition at line 131 of file OSGClusterServer.h. Referenced by doRender(), doSwap(), doSync(), getClusterWindow(), stop(), and windowChanged(). |
|
|
Definition at line 132 of file OSGClusterServer.h. Referenced by doSync(), getRemoteAspect(), start(), stop(), and ~ClusterServer(). |
|
|
Definition at line 133 of file OSGClusterServer.h. Referenced by acceptClient(), ClusterServer(), doSync(), and windowChanged(). |
|
|
Definition at line 134 of file OSGClusterServer.h. Referenced by acceptClient(). |
|
|
Definition at line 135 of file OSGClusterServer.h. Referenced by acceptClient(). |
|
|
Definition at line 136 of file OSGClusterServer.h. Referenced by acceptClient(). |
|
|
Definition at line 137 of file OSGClusterServer.h. Referenced by doRender(), doSwap(), and doSync(). |
|
|
Definition at line 138 of file OSGClusterServer.h. Referenced by acceptClient(), and setInterface(). |
1.4.3