void Server::incomingConnection( const qintptr socketHandle ) { QThread* workerThread = new QThread( this ); ServerWorker* worker = new ServerWorker( socketHandle ); worker->moveToThread( workerThread ); connect( workerThread, SIGNAL( started( )), worker, SLOT( initConnection( ))); connect( worker, SIGNAL( connectionClosed( )), workerThread, SLOT( quit( ))); // Make sure the thread will be deleted connect( workerThread, SIGNAL( finished( )), worker, SLOT( deleteLater( ))); connect( workerThread, SIGNAL( finished( )), workerThread, SLOT( deleteLater( ))); // public signals/slots, forwarding from/to worker connect( worker, SIGNAL( registerToEvents( QString, bool, deflect::EventReceiver* )), this, SIGNAL( registerToEvents( QString, bool, deflect::EventReceiver* ))); connect( this, SIGNAL( _pixelStreamerClosed( QString )), worker, SLOT( closeConnection( QString ))); connect( this, SIGNAL( _eventRegistrationReply( QString, bool )), worker, SLOT( replyToEventRegistration( QString, bool ))); // Commands connect( worker, SIGNAL( receivedCommand( QString, QString )), &_impl->commandHandler, SLOT( process( QString, QString ))); // PixelStreamDispatcher connect( worker, SIGNAL( addStreamSource( QString, size_t )), &_impl->pixelStreamDispatcher, SLOT(addSource( QString, size_t ))); connect( worker, SIGNAL( receivedSegement( QString, size_t, deflect::Segment )), &_impl->pixelStreamDispatcher, SLOT( processSegment( QString, size_t, deflect::Segment ))); connect( worker, SIGNAL( receivedFrameFinished( QString, size_t )), &_impl->pixelStreamDispatcher, SLOT( processFrameFinished( QString, size_t ))); connect( worker, SIGNAL( removeStreamSource( QString, size_t )), &_impl->pixelStreamDispatcher, SLOT( removeSource( QString, size_t ))); workerThread->start(); }
void ServerWorker::_handleMessage( const MessageHeader& messageHeader, const QByteArray& byteArray ) { const QString uri( messageHeader.uri ); if( uri.isEmpty( )) { std::cerr << "Warning: rejecting streamer with empty uri" << std::endl; closeConnection( _streamUri ); return; } if( uri != _streamUri && messageHeader.type != MESSAGE_TYPE_PIXELSTREAM_OPEN ) { std::cerr << "Warning: ingnoring message with incorrect stream uri: '" << messageHeader.uri << "', expected: '" << _streamUri.toStdString() << "'" << std::endl; return; } switch( messageHeader.type ) { case MESSAGE_TYPE_QUIT: emit removeStreamSource( _streamUri, _sourceId ); _streamUri = QString(); break; case MESSAGE_TYPE_PIXELSTREAM_OPEN: if( !_streamUri.isEmpty( )) { std::cerr << "Warning: PixelStream already opened!" << std::endl; return; } _streamUri = uri; emit addStreamSource( _streamUri, _sourceId ); break; case MESSAGE_TYPE_PIXELSTREAM_FINISH_FRAME: emit receivedFrameFinished( _streamUri, _sourceId ); break; case MESSAGE_TYPE_PIXELSTREAM: _handlePixelStreamMessage( byteArray ); break; case MESSAGE_TYPE_COMMAND: emit receivedCommand( QString( byteArray.data( )), _streamUri ); break; case MESSAGE_TYPE_SIZE_HINTS: { const SizeHints* hints = reinterpret_cast< const SizeHints* >( byteArray.data( )); emit receivedSizeHints( _streamUri, SizeHints( *hints )); break; } case MESSAGE_TYPE_BIND_EVENTS: case MESSAGE_TYPE_BIND_EVENTS_EX: if( _registeredToEvents ) std::cerr << "We are already bound!!" << std::endl; else { const bool exclusive = (messageHeader.type == MESSAGE_TYPE_BIND_EVENTS_EX); emit registerToEvents( _streamUri, exclusive, this ); } break; default: break; } }