How do check out IB's connection

Discussion in 'App Development' started by Xraptor, Jul 15, 2016.

  1. Xraptor

    Xraptor

    Code:
    IsConnected = true;
    
    while(true)
    {
                if (!ClientSocket.IsConnected())
                {
                    IsConnected = false;
                    MessageBox.Show("Connection was lost");
                }
    
                while (!ClientSocket.IsConnected()) { }
    
                if (!IsConnected)
                {
                    IsConnected = true;
                    MessageBox.Show("Connection restarted");
                }
    }
    Ran this the program, turned off wifi, waited a few minutes turned on wifi. And nothing, no Message!
    Why? I watching as IB gateway made reconnection but IsConnected always returned TRUE!
     
    Last edited: Jul 15, 2016
  2. marsman

    marsman

    It means, the code worked fine!
    It already has a connection (real or just the flag you have set), here it only loops endlessly...
    Check your logic; it's dangerous...
    :)

    Addendum: oh, you seem to mean you have an internet connection only via wifi.
    Hmm. don't know about that. I just remember from socket programming that it is not easy to detect a dropped socket connection; I vaguely remember one has to add some additional code at the low-level socket settings... Ie. setting the timeout-value to a much shorter time-frame...

    Addendum2:
    Code:
    bool IsConnected     (     )
        inline
    
    Notifies whether or not the API client is connected to the Host.
    
    Returns
        true if connection has been established, false if it has not.
    
    IsConnected() means the connection to the local TWS or local Gateway application.
    It does not mean the connection to the IB servers...
    So, turning off the LAN/WiFi doesn't affect the connection of an API client to the local API server (TWS) because that is usually using the 127.0.0.1 loopback IP (aka localhost) which is available even if there is no networking active... (assuming everything is on the same machine)
     
    Last edited: Jul 15, 2016
  3. Xraptor

    Xraptor

    Yes it already has been connected!
     
  4. marsman

    marsman

    Last edited: Jul 15, 2016
  5. Xraptor

    Xraptor

  6. conduit

    conduit

    Connecting and disconnecting and maintaining connections is a black box in IB's API to put it kindly. To be more direct: it was very poorly implemented. I recommend you set up your own heartbeat

     
  7. kmiklas

    kmiklas

    When I'm testing, I like to subscribe to a data feed for something, like Forex (which is free, I believe) or a busy US Equity (SPY, AAPL, etc.) if you've got the US Data Bundle.

    Then, just dump the incoming tickdata to the screen with (in C++) a cout or printf. You get a nice little stream of data points, with just this one line of code:

    Code:
    std::cout << price << " ";
    Inside the tickdata callback, this would print every price quote as it arrives. For example, with GBP/USD, you'd get the following zipping across your terminal screen:
    Code:
    1.33315 1.333152 1.33314 1.333121 1.33322 1.333114 1.33317 1.33314 etc..
    You also get some errors thrown if your connection is interrupted, or the data farm is unavailable, etc. This might help you to debug.

    I can post more info if you're interested.
     
  8. conduit

    conduit

    In a nutshell Cleary is talking about the need to implement a heartbeat or other keepalive check

     
  9. kmiklas

    kmiklas

    I had a similar problem and combed through the code a little while back.

    An isConnected() method exists in the test files, and is implemented as follows. I'm running C++ v9.72.14, and it does pretty much what you're looking for. You don't say what version (or what language) you're using, but this example may help you.

    Main.cpp: note how the while(client.isConnected) statement is called win the endless for (;;) loop. This is basically the keep-alive previously discussed.

    Code:
        for (;;) {
            ++attempt;
            printf( "Attempt %u of %u\n", attempt, MAX_ATTEMPTS);
            TestCppClient client(clientId, category, ticker, shares, bid, ask, stop);
            if(connectOptions) {
                client.setConnectOptions(connectOptions);
            }
            printf( "client.connect result: %d\n", client.connect(host, port, clientId));
            while( client.isConnected()) {
                client.processMessages();
            }
            if( attempt >= MAX_ATTEMPTS) { break;}
            printf( "Sleeping %u seconds before next attempt\n", SLEEP_TIME);
            sleep( SLEEP_TIME);
        }
        printf ( "End of C++ Socket Client Test\n");
    After the class TestCppClient is instantiated, the isConnected() method is available on the interface. Here is the definition:

    Code:
    bool TestCppClient::isConnected() const
    {
        return m_pClient->isConnected();
    }
    
    So you should be able to use this provided method. Just instantiate the class, and call the method.

    If you really want (or need) to get in deeper, there is more:

    From TestCppClient.h:
    m_pClient is pointer to an instance of EClientSocket.

    Code:
    private:
        //! [socket_declare]
        EClientSocket * const m_pClient;
    EClientSocket.h
    EClientSocket inherits from both EClient and EClientMsgSink:

    Code:
    class TWSAPIDLLEXP EClientSocket : public EClient, public EClientMsgSink
    {
    EClient: There's a few public methods here that may help.

    Code:
    EClient::ConnState EClient::connState() const
    {
        return m_connState;
    }
    
    bool EClient::isConnected() const
    {
        return m_connState == CS_CONNECTED;
    }
    
    bool EClient::isConnecting() const
    {
        return m_connState == CS_CONNECTING;
    }
    
    Note that ConnState is an enum. Perhaps the connState() method may be of use? Not that ConnState is an enum:

    Code:
        enum ConnState {
            CS_DISCONNECTED,
            CS_CONNECTING,
            CS_CONNECTED,
            CS_REDIRECT
        };
    EClient.cpp
    The actual connection request is in the following method. It is protected, so note that you're getting pretty deep in here.

    Code:
    int EClient::sendConnectRequest()
    {
        m_connState = CS_CONNECTING;
    
        int rval;
    
        // send client version
        std::stringstream msg;
        if( m_useV100Plus) {
            msg.write( API_SIGN, sizeof(API_SIGN));
            prepareBufferImpl( msg);
            if( MIN_CLIENT_VER < MAX_CLIENT_VER) {
                msg << 'v' << MIN_CLIENT_VER << ".." << MAX_CLIENT_VER;
            }
            else {
                msg << 'v' << MIN_CLIENT_VER;
            }
            if( !m_connectOptions.empty()) {
                msg << ' ' << m_connectOptions;
            }
    
            rval = closeAndSend( msg.str(), sizeof(API_SIGN));
        }
        else {
            ENCODE_FIELD( CLIENT_VERSION);
    
            rval = bufferedSend( msg.str());
        }
     
        m_connState = rval > 0 ? CS_CONNECTED : CS_DISCONNECTED;
    
        return rval;
    }
    You could dig into the closeAndSend() method from here...
     
    Last edited: Jul 16, 2016
  10. Xraptor

    Xraptor

    I use TWS API v9.72 C# but I couldn't find bufferedSend(),API_SIGN and closeAndSend() what is it?
     
    #10     Jul 16, 2016