Commit 9b33cadf authored by Nicolas Vuaille's avatar Nicolas Vuaille

Add option --disable-further-connections

In multi-clients mode, the master client can enable or disable the further
connections from the collaboration panel. Default is "enable".
With option --disable-further-connections, initial state is "disable".

The master client can change the connect-id of the server.

Connected clients are not disconnected when mode or connect-id is changed
in the server.
parent a509cb45
......@@ -64,6 +64,8 @@ static bool RealMain(int argc, char* argv[], vtkProcessModule::ProcessTypes type
vtkPVSessionServer* session = vtkPVSessionServer::New();
session->SetMultipleConnection(options->GetMultiClientMode() != 0);
session->SetDisableFurtherConnections(options->GetDisableFurtherConnections() != 0);
int process_id = controller->GetLocalProcessId();
if (process_id == 0)
{
......
......@@ -86,6 +86,11 @@ public:
*/
virtual bool GetPendingConnectionsPresent() = 0;
/**
* Enable/disable further connections for given port.
*/
virtual void DisableFurtherConnections(int port, bool disable) = 0;
protected:
vtkNetworkAccessManager();
~vtkNetworkAccessManager() override;
......
......@@ -54,6 +54,7 @@ vtkPVOptions::vtkPVOptions()
this->ClientMode = 0;
this->ServerMode = 0;
this->MultiClientMode = 0;
this->DisableFurtherConnections = 0;
this->MultiClientModeWithErrorMacro = 0;
this->MultiServerMode = 0;
this->RenderServerMode = 0;
......@@ -154,6 +155,11 @@ void vtkPVOptions::Initialize()
"While keeping the error macro on the server session for debug.",
vtkPVOptions::PVDATA_SERVER | vtkPVOptions::PVSERVER);
this->AddBooleanArgument("--disable-further-connections", 0, &this->DisableFurtherConnections,
"Disable further connections after the first client connects."
"Does nothing without --multi-clients enabled.",
vtkPVOptions::PVDATA_SERVER | vtkPVOptions::PVSERVER);
this->AddBooleanArgument("--multi-servers", 0, &this->MultiServerMode,
"Allow client to connect to several pvserver", vtkPVOptions::PVCLIENT);
......@@ -463,6 +469,12 @@ void vtkPVOptions::PrintSelf(ostream& os, vtkIndent indent)
{
os << indent << "Allow several clients to connect to a server.\n";
}
if (this->DisableFurtherConnections)
{
os << indent << "Disable further connections after the first client connects to a server..\n";
}
if (this->MultiServerMode)
{
os << indent << "Allow a client to connect to multiple servers at the same time.\n";
......
......@@ -135,6 +135,13 @@ public:
}
virtual int IsMultiClientModeDebug() { return this->MultiClientModeWithErrorMacro; }
//@{
/**
* Returns if this server does not allow connection after the first client.
*/
vtkGetMacro(DisableFurtherConnections, int);
//@}
//@{
/**
* Is this client allow multiple server connection in parallel
......@@ -295,6 +302,7 @@ protected:
int ClientMode;
int RenderServerMode;
int MultiClientMode;
int DisableFurtherConnections;
int MultiClientModeWithErrorMacro;
int MultiServerMode;
int SymmetricMPIMode;
......
......@@ -146,6 +146,31 @@ bool vtkTCPNetworkAccessManager::GetPendingConnectionsPresent()
return false;
}
//----------------------------------------------------------------------------
void vtkTCPNetworkAccessManager::DisableFurtherConnections(int port, bool disable)
{
if (disable)
{
if (this->Internals->ServerSockets.find(port) != this->Internals->ServerSockets.end())
{
this->Internals->ServerSockets.at(port)->CloseSocket();
this->Internals->ServerSockets.erase(port);
}
}
else
{
vtkServerSocket* server_socket = vtkServerSocket::New();
if (server_socket->CreateServer(port) != 0)
{
vtkErrorMacro("Failed to set up server socket.");
server_socket->Delete();
return;
}
this->Internals->ServerSockets[port] = server_socket;
server_socket->FastDelete();
}
}
//----------------------------------------------------------------------------
bool vtkTCPNetworkAccessManager::GetNetworkEventsAvailable()
{
......@@ -304,11 +329,12 @@ void vtkTCPNetworkAccessManager::PrintHandshakeError(int errorcode)
"**********************************************************************\n");
break;
case HANDSHAKE_DIFFERENT_CONNECTION_IDS:
vtkErrorMacro("\n"
"**********************************************************************\n"
" Connection failed during handshake. The server has a different connection id"
" than the client.\n"
"**********************************************************************\n");
vtkWarningMacro("\n"
" Wrong connect-id: \n"
" The client cannot connect to the server because their connection ids\n"
" are not the same. Change your connect-id and try again.\n");
this->InvokeEvent(vtkCommand::UserEvent);
break;
case HANDSHAKE_DIFFERENT_RENDERING_BACKENDS:
vtkErrorMacro("\n"
......
......@@ -96,6 +96,11 @@ public:
*/
bool GetPendingConnectionsPresent() VTK_OVERRIDE;
/**
* Enable/disable further connections for given port.
*/
virtual void DisableFurtherConnections(int port, bool disable) VTK_OVERRIDE;
protected:
vtkTCPNetworkAccessManager();
~vtkTCPNetworkAccessManager() override;
......
......@@ -235,6 +235,8 @@ message ClientsInformation {
optional string name = 2;
optional bool is_master = 3 [default = false];
optional bool follow_cam = 4 [default = false];
optional bool disable_further_connections = 5 [default = false];
optional uint32 connect_id = 6 [default = 0];
}
extend Message {
......
......@@ -97,13 +97,32 @@ public:
* Enable or Disable multi-connection support.
* The MultipleConnection is only used inside the DATA_SERVER to support
* several clients to connect to it.
* By default we allow collaboration (this->MultipleConnection = true)
* By default, collaboration is not allowed (this->MultipleConnection = false)
*/
vtkBooleanMacro(MultipleConnection, bool);
vtkSetMacro(MultipleConnection, bool);
vtkGetMacro(MultipleConnection, bool);
//@}
//@{
/**
* Enable or Disable further connections in muliple connection mode.
* By default, further connections are enabled. (this->DisableFurtherConnections = false)
*/
vtkBooleanMacro(DisableFurtherConnections, bool);
vtkGetMacro(DisableFurtherConnections, bool);
void SetDisableFurtherConnections(bool disable);
//@}
//@{
/**
* Set/Get the server connect-id.
* Default is 0.
*/
void SetConnectID(int newConnectID);
int GetConnectID();
//@}
void OnClientServerMessageRMI(void* message, int message_length);
void OnCloseSessionRMI();
......@@ -135,6 +154,7 @@ protected:
vtkMPIMToNSocketConnection* MPIMToNSocketConnection;
bool MultipleConnection;
bool DisableFurtherConnections;
class vtkInternals;
vtkInternals* Internal;
......
......@@ -66,7 +66,7 @@ public:
}
}
bool UpdateUserNamesAndMaster(vtkSMMessage* msg)
bool UpdateFromUsers(vtkSMMessage* msg)
{
bool findChanges = false;
this->DisableBroadcast = true;
......@@ -81,6 +81,16 @@ public:
{
findChanges = findChanges || (this->MultiProcessController->GetMasterController() != id);
this->MultiProcessController->SetMasterController(id);
if (this->ServerSession)
{
findChanges = findChanges || (this->ServerSession->GetDisableFurtherConnections() !=
user->disable_further_connections());
this->ServerSession->SetDisableFurtherConnections(user->disable_further_connections());
unsigned int serverConnectId = this->ServerSession->GetConnectID();
findChanges = findChanges || serverConnectId != user->connect_id();
this->ServerSession->SetConnectID(user->connect_id());
}
}
}
this->DisableBroadcast = false;
......@@ -111,6 +121,11 @@ public:
{
user->set_is_master(true);
}
if (this->ServerSession)
{
user->set_disable_further_connections(this->ServerSession->GetDisableFurtherConnections());
user->set_connect_id(this->ServerSession->GetConnectID());
}
}
return &this->ServerState;
......@@ -161,7 +176,7 @@ void vtkSICollaborationManager::PrintSelf(ostream& os, vtkIndent indent)
//----------------------------------------------------------------------------
void vtkSICollaborationManager::Push(vtkSMMessage* msg)
{
if (this->Internal->UpdateUserNamesAndMaster(msg) && this->Internal->CanBroadcast())
if (this->Internal->UpdateFromUsers(msg) && this->Internal->CanBroadcast())
{
this->BroadcastToClients(this->Internal->BuildServerStateMessage());
}
......
......@@ -42,6 +42,8 @@ public:
this->ObserverTag = 0;
this->Me = 0;
this->UserToFollow = 0;
this->DisableFurtherConnections = false;
this->ConnectID = 0;
this->Clear();
}
......@@ -102,11 +104,35 @@ public:
return false;
}
bool SetDisableFurtherConnections(bool disable)
{
if (disable != this->DisableFurtherConnections)
{
this->DisableFurtherConnections = disable;
this->UpdateState(this->UserToFollow == 0 ? this->Master : this->UserToFollow);
return true;
}
return false;
}
bool UpdateConnectID(int connectID)
{
if (this->ConnectID != connectID)
{
this->ConnectID = connectID;
this->UpdateState(this->UserToFollow == 0 ? this->Master : this->UserToFollow);
return true;
}
return false;
}
void Clear()
{
this->UserNames.clear();
this->Users.clear();
this->Master = 0;
this->ConnectID = 0;
this->DisableFurtherConnections = false;
this->State.Clear();
this->PendingCameraUpdate.Clear();
this->LocalCameraStateCache.clear();
......@@ -130,6 +156,8 @@ public:
{
user->set_follow_cam(true);
}
user->set_disable_further_connections(this->DisableFurtherConnections);
user->set_connect_id(this->ConnectID);
}
}
......@@ -157,6 +185,9 @@ public:
{
foundChanges = this->UpdateMaster(id) || foundChanges;
}
foundChanges =
this->SetDisableFurtherConnections(user->disable_further_connections()) || foundChanges;
foundChanges = this->UpdateConnectID(user->connect_id()) || foundChanges;
if (user->follow_cam())
{
......@@ -229,10 +260,12 @@ public:
int Me;
int UserToFollow;
int Master;
int ConnectID;
vtkSMMessage State;
vtkSMMessage PendingCameraUpdate;
std::map<int, vtkSMMessage> LocalCameraStateCache;
unsigned long ObserverTag;
bool DisableFurtherConnections;
};
//****************************************************************************
vtkStandardNewMacro(vtkSMCollaborationManager);
......@@ -291,6 +324,20 @@ void vtkSMCollaborationManager::LoadState(
}
}
//----------------------------------------------------------------------------
void vtkSMCollaborationManager::DisableFurtherConnections(bool disable)
{
this->Internal->SetDisableFurtherConnections(disable);
this->UpdateUserInformations();
}
//-----------------------------------------------------------------------------
void vtkSMCollaborationManager::SetConnectID(int connectID)
{
this->Internal->UpdateConnectID(connectID);
this->UpdateUserInformations();
}
//----------------------------------------------------------------------------
vtkTypeUInt32 vtkSMCollaborationManager::GetGlobalID()
{
......@@ -355,6 +402,13 @@ int vtkSMCollaborationManager::GetMasterId()
{
return this->Internal->Master;
}
//----------------------------------------------------------------------------
bool vtkSMCollaborationManager::GetDisableFurtherConnections()
{
return this->Internal->DisableFurtherConnections;
}
//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetUserId()
{
......@@ -417,6 +471,20 @@ void vtkSMCollaborationManager::UpdateUserInformations()
this->LoadState(&msg, NULL);
}
}
//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetServerConnectID()
{
return this->Internal->ConnectID;
}
//----------------------------------------------------------------------------
int vtkSMCollaborationManager::GetConnectID()
{
vtkSMSessionClient* session = vtkSMSessionClient::SafeDownCast(this->GetSession());
return session ? session->GetConnectID() : -1;
}
//----------------------------------------------------------------------------
void vtkSMCollaborationManager::SetSession(vtkSMSession* session)
{
......
......@@ -99,6 +99,11 @@ public:
*/
virtual int GetMasterId();
/**
* Return true if further connections are disabled.
*/
bool GetDisableFurtherConnections();
/**
* Return the id of the current client
*/
......@@ -136,6 +141,17 @@ public:
*/
void UpdateUserInformations();
/**
* Return the server connect id if this is the master.
* Else return -1.
*/
int GetServerConnectID();
/**
* Return the client connect id.
*/
int GetConnectID();
enum EventType
{
CollaborationNotification = 12345,
......@@ -162,6 +178,18 @@ public:
*/
void LoadState(const vtkSMMessage* msg, vtkSMProxyLocator* locator) VTK_OVERRIDE;
/**
* Enable or disable further connections to the server.
* Already connected clients stay connected.
*/
void DisableFurtherConnections(bool disable);
/**
* Change the connect-id. Already connected clients stay connected.
* @param connectID the new connect-id for the server.
*/
void SetConnectID(int connectID);
protected:
/**
* Default constructor.
......
......@@ -1009,3 +1009,11 @@ vtkSMCollaborationManager* vtkSMSessionClient::GetCollaborationManager()
}
return this->CollaborationCommunicator;
}
//-----------------------------------------------------------------------------
int vtkSMSessionClient::GetConnectID()
{
vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
vtkPVOptions* options = pm->GetOptions();
return options->GetConnectID();
}
......@@ -176,6 +176,11 @@ public:
*/
vtkSMCollaborationManager* GetCollaborationManager() VTK_OVERRIDE;
/**
* Return the connect id of this client.
*/
int GetConnectID();
//---------------------------------------------------------------------------
// API for GlobalId management
//---------------------------------------------------------------------------
......
......@@ -130,6 +130,66 @@
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="masterControl" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="disableFurtherConnections">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Disable further connections</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="connectIdLabel">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>Server Connect ID </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="connectId">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
......
......@@ -50,7 +50,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqView.h"
#include "vtkEventQtSlotConnect.h"
#include "vtkPVServerInformation.h"
#include "vtkProcessModule.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSMCollaborationManager.h"
#include "vtkSMMessage.h"
......@@ -95,6 +95,9 @@ pqCollaborationPanel::pqCollaborationPanel(QWidget* p)
#endif
this->Internal->CameraToFollowOfUserId = -1;
this->Internal->NeedToConnectToCollaborationManager = true;
this->Internal->connectId->setMaximum(VTK_INT_MAX);
this->Internal->disableFurtherConnections->setChecked(false);
this->Internal->masterControl->setVisible(false);
QObject::connect(this->Internal->message, SIGNAL(returnPressed()), this, SLOT(onUserMessage()));
......@@ -107,6 +110,12 @@ pqCollaborationPanel::pqCollaborationPanel(QWidget* p)
QObject::connect(this->Internal->shareMousePointer, SIGNAL(clicked(bool)), this,
SIGNAL(shareLocalMousePointer(bool)));
QObject::connect(this->Internal->disableFurtherConnections, SIGNAL(clicked(bool)), this,
SIGNAL(disableFurtherConnections(bool)));
QObject::connect(
this->Internal->connectId, SIGNAL(editingFinished()), this, SLOT(onConnectIDChanged()));
QObject::connect(this, SIGNAL(triggerChatMessage(pqServer*, int, QString&)), this,
SLOT(writeChatMessage(pqServer*, int, QString&)));
......@@ -134,6 +143,12 @@ pqCollaborationPanel::~pqCollaborationPanel()
QObject::disconnect(this->Internal->shareMousePointer, SIGNAL(clicked(bool)), this,
SIGNAL(shareLocalMousePointer(bool)));
QObject::disconnect(this->Internal->disableFurtherConnections, SIGNAL(clicked(bool)), this,
SIGNAL(disableFurtherConnections(bool)));
QObject::disconnect(
this->Internal->connectId, SIGNAL(editingFinished()), this, SLOT(onConnectIDChanged()));
QObject::disconnect(this, SIGNAL(triggerChatMessage(pqServer*, int, QString&)), this,
SLOT(writeChatMessage(pqServer*, int, QString&)));
......@@ -155,6 +170,11 @@ pqCollaborationPanel::~pqCollaborationPanel()
QObject::disconnect(
this, SIGNAL(shareLocalMousePointer(bool)), collab, SLOT(enableMousePointerSharing(bool)));
QObject::disconnect(
this, SIGNAL(disableFurtherConnections(bool)), collab, SLOT(disableFurtherConnections(bool)));
QObject::disconnect(this, SIGNAL(connectIDChanged(int)), collab, SLOT(setConnectID(int)));
QObject::disconnect(collab, SIGNAL(triggeredMasterUser(int)), this, SLOT(onNewMaster(int)));
QObject::disconnect(
......@@ -303,7 +323,14 @@ void pqCollaborationPanel::onNewMaster(int masterId)
this->Internal->members->item(i, 0)->setIcon(QIcon());
}
}
vtkSMCollaborationManager* collabManager = this->getSMCollaborationManager();
if (collabManager != NULL)
{
this->Internal->masterControl->setVisible(collabManager->IsMaster());
}
}
//-----------------------------------------------------------------------------
void pqCollaborationPanel::promoteToMaster(int masterId)
{
......@@ -347,9 +374,14 @@ void pqCollaborationPanel::onUserUpdate()
if (!collab)
{
this->Internal->members->setRowCount(0);
this->Internal->masterControl->setVisible(false);
return;
}
int nbUsers = collab->GetNumberOfConnectedClients();
this->Internal->masterControl->setVisible(collab->IsMaster());
this->Internal->disableFurtherConnections->setChecked(collab->GetDisableFurtherConnections());
this->Internal->connectId->setValue(collab->GetServerConnectID());
int userId;
QString userName;
this->Internal->members->setRowCount(nbUsers);
......@@ -451,6 +483,11 @@ void pqCollaborationPanel::onServerChanged()
QObject::connect(
this, SIGNAL(shareLocalMousePointer(bool)), collab, SLOT(enableMousePointerSharing(bool)));
QObject::connect(this, SIGNAL(disableFurtherConnections(bool)), collab,
SLOT(disableFurtherConnections(bool)));
QObject::connect(this, SIGNAL(connectIDChanged(int)), collab, SLOT(setConnectID(int)));
QObject::connect(collab, SIGNAL(triggeredMasterUser(int)), this, SLOT(onNewMaster(int)));
QObject::connect(collab, SIGNAL(triggerFollowCamera(int)), this, SLOT(followUserCamera(int)));
......@@ -463,3 +500,9 @@ void pqCollaborationPanel::onServerChanged()
}
}
}
//-----------------------------------------------------------------------------
void pqCollaborationPanel::onConnectIDChanged()
{
emit connectIDChanged(this->Internal->connectId->value());
}
......@@ -69,12 +69,23 @@ signals:
*/
void shareLocalMousePointer(bool);
/**
* This signal is triggered when user has allowed/disallowed
* further connections to the server.
*/
void disableFurtherConnections(bool);
/**
* This get triggered internally when it's not a good time to update the camera
* so the request get pushed to QueuedConnection
*/
void delayUpdateCamera(vtkSMMessage* msg);
/**
* This signal is triggered when user changes the connect-id.
*/
void connectIDChanged(int);
public slots:
/**
* Called by pqCollaborationManager when a message is received
......@@ -121,6 +132,11 @@ protected slots:
void onServerChanged();
/**
* Called when the user changes the connect-id. Emit signal with new value.
*/
void onConnectIDChanged();
protected:
/**
* Promote a new master
......
......@@ -436,6 +436,25 @@ void pqCollaborationManager::enableMousePointerSharing(bool enable)
{
this->Internals->BroadcastMouseLocation = enable;
}
//-----------------------------------------------------------------------------
void pqCollaborationManager::disableFurtherConnections(bool disable)
{
if (this->Internals->ActiveCollaborationManager)
{
this->Internals->ActiveCollaborationManager->DisableFurtherConnections(disable);
}
}
//-----------------------------------------------------------------------------
void pqCollaborationManager::setConnectID(int connectID)
{
if (this->Internals->ActiveCollaborationManager)
{
this->Internals->ActiveCollaborationManager->SetConnectID(connectID);
}
}
//-----------------------------------------------------------------------------
void pqCollaborationManager::onChartViewChange(vtkTypeUInt32 gid, double* bounds)
{
......
......@@ -156,6 +156,16 @@ public slots:
*/
void enableMousePointerSharing(bool);
/**
* Enable/disable further connections to the server.
*/
void disableFurtherConnections(bool disable);
/**
* Set the connect-id.
*/
void setConnectID(int connectID);
private slots:
/**
* Called when a message has been sent by another client
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment