MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkIGTLServer.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
13#include "mitkIGTLServer.h"
14#include <cstdio>
15
16#include <itksys/SystemTools.hxx>
17
18#include <igtlServerSocket.h>
19#include <igtlTrackingDataMessage.h>
20#include <igtlImageMessage.h>
21#include <mitkIGTLStatus.h>
22
24IGTLDevice(ReadFully)
25{
26}
27
31
33{
34 if (this->GetState() != Setup)
35 {
36 mitkThrowException(mitk::Exception) <<
37 "Can only try to create a server if in setup mode";
38 return false;
39 }
40
41 int portNumber = this->GetPortNumber();
42
43 if (portNumber == -1)
44 {
45 //port number was not correct
46 return false;
47 }
48
49 //create a new server socket
50 m_Socket = igtl::ServerSocket::New();
51
52 //try to create the igtl server
53 int response = dynamic_cast<igtl::ServerSocket*>(m_Socket.GetPointer())->
54 CreateServer(portNumber);
55
56 //check the response
57 if (response != 0)
58 {
59 mitkThrowException(mitk::Exception) <<
60 "The server could not be created. Port: " << portNumber;
61 return false;
62 }
63
64 // everything is initialized and connected so the communication can be started
65 this->SetState(Ready);
66
67 return true;
68}
69
71{
72 //remove all registered clients
73 m_SentListMutex.lock();
74 m_ReceiveListMutex.lock();
75 SocketListType allRegisteredSockets(m_RegisteredClients);
76 m_SentListMutex.unlock();
77 m_ReceiveListMutex.unlock();
78 this->StopCommunicationWithSocket(allRegisteredSockets);
79
81}
82
84{
85 igtl::Socket::Pointer socket;
86 //check if another igtl device wants to connect to this socket
87 socket =
88 ((igtl::ServerSocket*)(this->m_Socket.GetPointer()))->WaitForConnection(1);
89 //if there is a new connection the socket is not null
90 if (socket.IsNotNull())
91 {
92 //add the new client socket to the list of registered clients
93 m_SentListMutex.lock();
94 m_ReceiveListMutex.lock();
95 this->m_RegisteredClients.push_back(socket);
96 m_SentListMutex.unlock();
97 m_ReceiveListMutex.unlock();
98 //inform observers about this new client
99 this->InvokeEvent(NewClientConnectionEvent());
100 MITK_INFO("IGTLServer") << "Connected to a new client: " << socket;
101 }
102}
103
105{
106 unsigned int status = IGTL_STATUS_OK;
107 SocketListType socketsToBeRemoved;
108
109 //the server can be connected with several clients, therefore it has to check
110 //all registered clients
112 m_ReceiveListMutex.lock();
113 auto it_end = this->m_RegisteredClients.end();
114 for (it = this->m_RegisteredClients.begin(); it != it_end; ++it)
115 {
116 //it is possible that ReceivePrivate detects that the current socket is
117 //already disconnected. Therefore, it is necessary to remove this socket
118 //from the registered clients list
119 status = this->ReceivePrivate(*it);
120 if (status == IGTL_STATUS_NOT_PRESENT)
121 {
122 //remember this socket for later, it is not a good idea to remove it
123 //from the list directly because we iterate over the list at this point
124 socketsToBeRemoved.push_back(*it);
125 MITK_WARN("IGTLServer") << "Lost connection to a client socket. ";
126 }
127 else if (status != 1)
128 {
129 MITK_DEBUG("IGTLServer") << "IGTL Message with status: " << status;
130 }
131 }
132 m_ReceiveListMutex.unlock();
133 if (socketsToBeRemoved.size() > 0)
134 {
135 //remove the sockets that are not connected anymore
136 this->StopCommunicationWithSocket(socketsToBeRemoved);
137 //inform observers about loosing the connection to these sockets
138 this->InvokeEvent(LostConnectionEvent());
139 }
140}
141
143{
144 //get the latest message from the queue
145 mitk::IGTLMessage::Pointer curMessage = this->m_MessageQueue->PullSendMessage();
146
147 // there is no message => return
148 if (curMessage.IsNull())
149 return;
150
151 //the server can be connected with several clients, therefore it has to check
152 //all registered clients
153 //sending a message to all registered clients might not be the best solution,
154 //it could be better to store the client together with the requested type. Then
155 //the data would be send to the appropriate client and to noone else.
156 //(I know it is no excuse but PLUS is doing exactly the same, they broadcast
157 //everything)
158 m_SentListMutex.lock();
160 auto it_end =
161 this->m_RegisteredClients.end();
162 for (it = this->m_RegisteredClients.begin(); it != it_end; ++it)
163 {
164 //maybe there should be a check here if the current socket is still active
165 this->SendMessagePrivate(curMessage, *it);
166 MITK_DEBUG("IGTLServer") << "Sent IGTL Message";
167 }
168 m_SentListMutex.unlock();
169}
170
172 SocketListType& toBeRemovedSockets)
173{
174 for (auto i = toBeRemovedSockets.begin(); i != toBeRemovedSockets.end(); i++)
175 this->StopCommunicationWithSocket(*i);
176}
177
179{
180 m_SentListMutex.lock();
181 m_ReceiveListMutex.lock();
182 auto i = m_RegisteredClients.begin();
183 auto end = m_RegisteredClients.end();
184 while (i != end)
185 {
186 if ((*i) == client)
187 {
188 // //close the socket
189 (*i)->CloseSocket();
190 //and remove it from the list
191 i = this->m_RegisteredClients.erase(i);
192 MITK_INFO("IGTLServer") << "Removed client socket from server client list.";
193 break;
194 }
195 else
196 {
197 ++i;
198 }
199 }
200 m_SentListMutex.unlock();
201 m_ReceiveListMutex.unlock();
202}
203
205{
206 return this->m_RegisteredClients.size();
207}
Interface for all OpenIGTLink Devices.
virtual bool CloseConnection()
Closes the connection to the device.
virtual void StopCommunicationWithSocket(SocketListType &toBeRemovedSockets)
Stops the communication with the given sockets.
unsigned int GetNumberOfConnections() override
Returns the number of client connections of this device.
bool CloseConnection() override
Closes the connection to the device.
bool OpenConnection() override
Initialize the connection for the IGTLServer.
void Send() override
Call this method to send a message. The message will be read from the queue. So far the message is se...
void Receive() override
Call this method to receive a message.
std::list< igtl::Socket::Pointer > SocketListType
IGTLServer(bool ReadFully)
SocketListType::iterator SocketListIteratorType
void Connect() override
Call this method to check for other devices that want to connect to this one.
#define IGTL_STATUS_OK
#define IGTL_STATUS_NOT_PRESENT