SocketInitiator.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (c) 2001-2014
3 **
4 ** This file is part of the QuickFIX FIX Engine
5 **
6 ** This file may be distributed under the terms of the quickfixengine.org
7 ** license as defined by quickfixengine.org and appearing in the file
8 ** LICENSE included in the packaging of this file.
9 **
10 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 **
13 ** See http://www.quickfixengine.org/LICENSE for licensing information.
14 **
15 ** Contact ask@quickfixengine.org if any conditions of this licensing are
16 ** not clear to you.
17 **
18 ****************************************************************************/
19 
20 #ifdef _MSC_VER
21 #include "stdafx.h"
22 #else
23 #include "config.h"
24 #endif
25 
26 #include "SocketInitiator.h"
27 #include "Session.h"
28 #include "Settings.h"
29 
30 namespace FIX
31 {
32 SocketInitiator::SocketInitiator( Application& application,
33  MessageStoreFactory& factory,
34  const SessionSettings& settings )
35 throw( ConfigError )
36 : Initiator( application, factory, settings ),
37  m_connector( 1 ), m_lastConnect( 0 ),
38  m_reconnectInterval( 30 ), m_noDelay( false ), m_sendBufSize( 0 ),
39  m_rcvBufSize( 0 )
40 {
41 }
42 
43 SocketInitiator::SocketInitiator( Application& application,
44  MessageStoreFactory& factory,
45  const SessionSettings& settings,
46  LogFactory& logFactory )
47 throw( ConfigError )
48 : Initiator( application, factory, settings, logFactory ),
49  m_connector( 1 ), m_lastConnect( 0 ),
50  m_reconnectInterval( 30 ), m_noDelay( false ), m_sendBufSize( 0 ),
51  m_rcvBufSize( 0 )
52 {
53 }
54 
56 {
57  SocketConnections::iterator i;
58  for (i = m_connections.begin();
59  i != m_connections.end(); ++i)
60  delete i->second;
61 
62  for (i = m_pendingConnections.begin();
63  i != m_pendingConnections.end(); ++i)
64  delete i->second;
65 }
66 
68 throw ( ConfigError )
69 {
70  const Dictionary& dict = s.get();
71 
72  if( dict.has( RECONNECT_INTERVAL ) )
73  m_reconnectInterval = dict.getInt( RECONNECT_INTERVAL );
74  if( dict.has( SOCKET_NODELAY ) )
75  m_noDelay = dict.getBool( SOCKET_NODELAY );
76  if( dict.has( SOCKET_SEND_BUFFER_SIZE ) )
77  m_sendBufSize = dict.getInt( SOCKET_SEND_BUFFER_SIZE );
78  if( dict.has( SOCKET_RECEIVE_BUFFER_SIZE ) )
79  m_rcvBufSize = dict.getInt( SOCKET_RECEIVE_BUFFER_SIZE );
80 }
81 
83 throw ( RuntimeError )
84 {
85 }
86 
88 {
89  connect();
90 
91  while ( !isStopped() ) {
92  m_connector.block( *this, false, 1.0 );
94  }
95 
96  time_t start = 0;
97  time_t now = 0;
98 
99  ::time( &start );
100  while ( isLoggedOn() )
101  {
102  m_connector.block( *this );
103  if( ::time(&now) -5 >= start )
104  break;
105  }
106 }
107 
108 bool SocketInitiator::onPoll( double timeout )
109 {
110  time_t start = 0;
111  time_t now = 0;
112 
113  if( isStopped() )
114  {
115  if( start == 0 )
116  ::time( &start );
117  if( !isLoggedOn() )
118  return false;
119  if( ::time(&now) - 5 >= start )
120  return false;
121  }
122 
123  m_connector.block( *this, true, timeout );
124  return true;
125 }
126 
128 {
129 }
130 
131 void SocketInitiator::doConnect( const SessionID& s, const Dictionary& d )
132 {
133  try
134  {
135  std::string address;
136  short port = 0;
137  std::string sourceAddress;
138  short sourcePort = 0;
139 
140  Session* session = Session::lookupSession( s );
141  if( !session->isSessionTime(UtcTimeStamp()) ) return;
142 
143  Log* log = session->getLog();
144 
145  getHost( s, d, address, port, sourceAddress, sourcePort );
146 
147  log->onEvent( "Connecting to " + address + " on port " + IntConvertor::convert((unsigned short)port) + " (Source " + sourceAddress + ":" + IntConvertor::convert((unsigned short)sourcePort) + ")");
148  int result = m_connector.connect( address, port, m_noDelay, m_sendBufSize, m_rcvBufSize, sourceAddress, sourcePort );
149  setPending( s );
150 
151  m_pendingConnections[ result ]
152  = new SocketConnection( *this, s, result, &m_connector.getMonitor() );
153  }
154  catch ( std::exception& ) {}
155 }
156 
157 void SocketInitiator::onConnect( SocketConnector&, int s )
158 {
159  SocketConnections::iterator i = m_pendingConnections.find( s );
160  if( i == m_pendingConnections.end() ) return;
161  SocketConnection* pSocketConnection = i->second;
162 
163  m_connections[s] = pSocketConnection;
164  m_pendingConnections.erase( i );
165  setConnected( pSocketConnection->getSession()->getSessionID() );
166  pSocketConnection->onTimeout();
167 }
168 
169 void SocketInitiator::onWrite( SocketConnector& connector, int s )
170 {
171  SocketConnections::iterator i = m_connections.find( s );
172  if ( i == m_connections.end() ) return ;
173  SocketConnection* pSocketConnection = i->second;
174  if( pSocketConnection->processQueue() )
175  pSocketConnection->unsignal();
176 }
177 
178 bool SocketInitiator::onData( SocketConnector& connector, int s )
179 {
180  SocketConnections::iterator i = m_connections.find( s );
181  if ( i == m_connections.end() ) return false;
182  SocketConnection* pSocketConnection = i->second;
183  return pSocketConnection->read( connector );
184 }
185 
187 {
188  SocketConnections::iterator i = m_connections.find( s );
189  SocketConnections::iterator j = m_pendingConnections.find( s );
190 
191  SocketConnection* pSocketConnection = 0;
192  if( i != m_connections.end() )
193  pSocketConnection = i->second;
194  if( j != m_pendingConnections.end() )
195  pSocketConnection = j->second;
196  if( !pSocketConnection )
197  return;
198 
199  setDisconnected( pSocketConnection->getSession()->getSessionID() );
200 
201  Session* pSession = pSocketConnection->getSession();
202  if ( pSession )
203  {
204  pSession->disconnect();
205  setDisconnected( pSession->getSessionID() );
206  }
207 
208  delete pSocketConnection;
209  m_connections.erase( s );
210  m_pendingConnections.erase( s );
211 }
212 
213 void SocketInitiator::onError( SocketConnector& connector )
214 {
215  onTimeout( connector );
216 }
217 
218 void SocketInitiator::onTimeout( SocketConnector& )
219 {
220  time_t now;
221  ::time( &now );
222 
223  if ( (now - m_lastConnect) >= m_reconnectInterval )
224  {
225  connect();
226  m_lastConnect = now;
227  }
228 
229  SocketConnections::iterator i;
230  for ( i = m_connections.begin(); i != m_connections.end(); ++i )
231  i->second->onTimeout();
232 }
233 
234 void SocketInitiator::getHost( const SessionID& s, const Dictionary& d,
235  std::string& address, short& port,
236  std::string& sourceAddress, short& sourcePort)
237 {
238  int num = 0;
239  SessionToHostNum::iterator i = m_sessionToHostNum.find( s );
240  if ( i != m_sessionToHostNum.end() ) num = i->second;
241 
242  std::stringstream hostStream;
243  hostStream << SOCKET_CONNECT_HOST << num;
244  std::string hostString = hostStream.str();
245 
246  std::stringstream portStream;
247  portStream << SOCKET_CONNECT_PORT << num;
248  std::string portString = portStream.str();
249 
250  sourcePort = 0;
251  sourceAddress.empty();
252 
253  if( d.has(hostString) && d.has(portString) )
254  {
255  address = d.getString( hostString );
256  port = ( short ) d.getInt( portString );
257 
258  std::stringstream sourceHostStream;
259  sourceHostStream << SOCKET_CONNECT_SOURCE_HOST << num;
260  hostString = sourceHostStream.str();
261  if( d.has(hostString) )
262  sourceAddress = d.getString( hostString );
263 
264  std::stringstream sourcePortStream;
265  sourcePortStream << SOCKET_CONNECT_SOURCE_PORT << num;
266  portString = sourcePortStream.str();
267  if( d.has(portString) )
268  sourcePort = ( short ) d.getInt( portString );
269  }
270  else
271  {
272  num = 0;
273  address = d.getString( SOCKET_CONNECT_HOST );
274  port = ( short ) d.getInt( SOCKET_CONNECT_PORT );
275 
277  sourceAddress = d.getString( SOCKET_CONNECT_SOURCE_HOST );
279  sourcePort = ( short ) d.getInt( SOCKET_CONNECT_SOURCE_PORT );
280  }
281 
282  m_sessionToHostNum[ s ] = ++num;
283 }
284 }
FIX::SocketInitiator::onError
void onError(SocketConnector &)
Definition: SocketInitiator.cpp:230
FIX::Initiator::start
void start()
Start initiator.
Definition: Initiator.cpp:207
FIX::SOCKET_RECEIVE_BUFFER_SIZE
const char SOCKET_RECEIVE_BUFFER_SIZE[]
Definition: SessionSettings.h:87
FIX::SocketInitiator::onConnect
void onConnect(SocketConnector &, int)
Definition: SocketInitiator.cpp:174
FIX::SocketInitiator::m_connector
SocketConnector m_connector
Definition: SocketInitiator.h:103
FIX::SocketInitiator::SocketInitiator
SocketInitiator(Application &, MessageStoreFactory &, const SessionSettings &)
Definition: SocketInitiator.cpp:49
FIX::SocketInitiator::onInitialize
void onInitialize(const SessionSettings &)
Implemented to initialize initiator.
Definition: SocketInitiator.cpp:99
FIX::Session::lookupSession
static Session * lookupSession(const SessionID &)
Definition: Session.cpp:1513
FIX::SOCKET_NODELAY
const char SOCKET_NODELAY[]
Definition: SessionSettings.h:85
FIX::SocketInitiator::m_connections
SocketConnections m_connections
Definition: SocketInitiator.h:105
FIX::Dictionary::getString
std::string getString(const std::string &, bool capitalize=false) const
Get a value as a string.
Definition: Dictionary.cpp:49
FIX::SOCKET_CONNECT_SOURCE_PORT
const char SOCKET_CONNECT_SOURCE_PORT[]
Definition: SessionSettings.h:84
FIX::Dictionary::getInt
int getInt(const std::string &) const
Get a value as a int.
Definition: Dictionary.cpp:62
FIX::Initiator::connect
void connect()
Definition: Initiator.cpp:148
FIX::Session::getSessionID
const SessionID & getSessionID() const
Definition: Session.h:109
FIX::SocketInitiator::getHost
void getHost(const SessionID &, const Dictionary &, std::string &, short &, std::string &, short &)
Definition: SocketInitiator.cpp:251
FIX::SOCKET_CONNECT_SOURCE_HOST
const char SOCKET_CONNECT_SOURCE_HOST[]
Definition: SessionSettings.h:83
FIX::SOCKET_SEND_BUFFER_SIZE
const char SOCKET_SEND_BUFFER_SIZE[]
Definition: SessionSettings.h:86
FIX::ConfigError
Application is not configured correctly
Definition: Exceptions.h:104
FIX::RuntimeError
Application encountered serious error during runtime
Definition: Exceptions.h:111
FIX::SessionID
Unique session id consists of BeginString, SenderCompID and TargetCompID.
Definition: SessionID.h:47
FIX::Initiator::isLoggedOn
bool isLoggedOn()
Check to see if any sessions are currently logged on.
Definition: Initiator.cpp:292
FIX::SocketInitiator::m_sendBufSize
int m_sendBufSize
Definition: SocketInitiator.h:109
FIX::SocketConnector
Connects sockets to remote ports and addresses.
Definition: SocketConnector.h:52
FIX::SocketInitiator::m_pendingConnections
SocketConnections m_pendingConnections
Definition: SocketInitiator.h:104
FIX::TYPE::UtcTimeStamp
@ UtcTimeStamp
Definition: FieldTypes.h:940
FIX::SocketInitiator::onConfigure
void onConfigure(const SessionSettings &)
Implemented to configure acceptor.
Definition: SocketInitiator.cpp:84
FIX::SessionSettings
Container for setting dictionaries mapped to sessions.
Definition: SessionSettings.h:237
FIX::IntConvertor::convert
static std::string convert(signed_int value)
Definition: FieldConvertors.h:170
FIX::SocketInitiator::onDisconnect
void onDisconnect(SocketConnector &, int)
Definition: SocketInitiator.cpp:203
FIX::RECONNECT_INTERVAL
const char RECONNECT_INTERVAL[]
Definition: SessionSettings.h:88
FIX::SocketInitiator::onWrite
void onWrite(SocketConnector &, int)
Definition: SocketInitiator.cpp:186
FIX::Dictionary::has
bool has(const std::string &) const
Check if the dictionary contains a value for key.
Definition: Dictionary.cpp:166
FIX::SocketInitiator::m_reconnectInterval
int m_reconnectInterval
Definition: SocketInitiator.h:107
FIX::SocketInitiator::m_noDelay
bool m_noDelay
Definition: SocketInitiator.h:108
FIX::Initiator::setDisconnected
void setDisconnected(const SessionID &)
Definition: Initiator.cpp:180
FIX::SocketConnection::getSession
Session * getSession() const
Definition: SocketConnection.h:73
FIX::SocketInitiator::m_lastConnect
time_t m_lastConnect
Definition: SocketInitiator.h:106
FIX::SocketInitiator::m_rcvBufSize
int m_rcvBufSize
Definition: SocketInitiator.h:110
Settings.h
FIX::SocketConnector::connect
int connect(const std::string &address, int port, bool noDelay, int sendBufSize, int rcvBufSize, const std::string &sourceAddress="", int sourcePort=0)
Definition: SocketConnector.cpp:102
FIX::Dictionary::getBool
bool getBool(const std::string &) const
Get a value as a bool.
Definition: Dictionary.cpp:88
FIX::Initiator::setPending
void setPending(const SessionID &)
Definition: Initiator.cpp:162
FIX::SocketInitiator::onStop
void onStop()
Implemented to stop a running initiator.
Definition: SocketInitiator.cpp:144
FIX::SOCKET_CONNECT_PORT
const char SOCKET_CONNECT_PORT[]
Definition: SessionSettings.h:82
FIX
Definition: Acceptor.cpp:34
FIX::Initiator::setConnected
void setConnected(const SessionID &)
Definition: Initiator.cpp:171
FIX::SocketInitiator::onTimeout
void onTimeout(SocketConnector &)
Definition: SocketInitiator.cpp:235
FIX::SocketConnector::getMonitor
SocketMonitor & getMonitor()
Definition: SocketConnector.h:82
FIX::SocketInitiator::~SocketInitiator
virtual ~SocketInitiator()
Definition: SocketInitiator.cpp:72
FIX::Session::disconnect
void disconnect()
Definition: Session.cpp:630
Session.h
FIX::SocketInitiator::onPoll
bool onPoll(double timeout)
Implemented to connect and poll for events.
Definition: SocketInitiator.cpp:125
FIX::SocketConnection::read
bool read(SocketConnector &s)
Definition: SocketConnection.cpp:123
SocketInitiator.h
FIX::SocketConnector::block
void block(Strategy &strategy, bool poll=0, double timeout=0.0)
Definition: SocketConnector.cpp:131
FIX::SocketInitiator::doConnect
void doConnect(const SessionID &, const Dictionary &d)
Implemented to connect a session to its target.
Definition: SocketInitiator.cpp:148
FIX::SocketInitiator::onStart
void onStart()
Implemented to start connecting to targets.
Definition: SocketInitiator.cpp:104
FIX::SocketInitiator::m_sessionToHostNum
SessionToHostNum m_sessionToHostNum
Definition: SocketInitiator.h:102
FIX::Initiator::isStopped
bool isStopped()
Definition: Initiator.h:100
FIX::Dictionary
For storage and retrieval of key/value pairs.
Definition: Dictionary.h:53
FIX::SocketConnection
Encapsulates a socket file descriptor (single-threaded).
Definition: SocketConnection.h:63
FIX::SocketInitiator::onData
bool onData(SocketConnector &, int)
Definition: SocketInitiator.cpp:195
FIX::Session
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:62
FIX::SOCKET_CONNECT_HOST
const char SOCKET_CONNECT_HOST[]
Definition: SessionSettings.h:81

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001