10 years, 8 months ago.

Server becomes unresponsive - what am I doing wrong?

Hi Henry, Thanks for this HTTPServer, it looks to be just what I need. I have got it working processing RPC requests (RPCVariable read, write, and query available variables), and returning a simple HTML page. However, it only processes 3 or 4 requests before becoming unresponsive. At that stage the rest of my program continues working normally while it regularly pools the server using the svr.pool() call, but the client side never gets serviced. In fact I get the same result if I compile your program https://mbed.org/users/leihen/code/EthHTTPServer/.

Do you have this issue with the server or am I doing something silly - I'm still a relative novice with c++.

Thanks David.

Question relating to:

1 Answer

10 years, 8 months ago.

Hello David, a similar issue has been reported to me a few weeks ago. The problem does not seem to be caused by the classes provided by me rather than in the Ethernet Library. Anyway, I am currently still on vacation and will be looking into this issue until end of the week when I am back home. Henry

Accepted Answer

Hi Henry,

Thanks for the reply. I hope that you have had a good holiday.

While you are working on your code, I wonder if you would consider a modification. I would really like to use the EthernetInterface class to initialise and connect to the internet first in order use NTP to set the time and also to display the allocated IP address. Could you pass through the eth parameter to the HTTPServer class start function, possibly using a default for compatibility with what you currently have defined?

On the program side I want to do something like this:

    EthernetInterface eth;
    int ethernetStatus = eth.init();
    if (ethernetStatus == 0)
        ethernetStatus = eth.connect();
    if (ethernetStatus == 0){
        lcd.printf("Ethernet OK");
        ethernetAvailable = true;
        if (ntp.setTime("0.pool.ntp.org") == 0)
            lcd.printf("%s", eth.getIPAddress());
    } else
        lcd.printf("No Ethernet");

  .... more code...

    if (ethernetAvailable){   // Set up the server
        HTTPFsRequestHandler::mount("/sd/www/", "/");
        svr.addHandler<HTTPFsRequestHandler>("/");
        svr.addHandler<HTTPRpcRequestHandler>("/rpc");  // Enable RPC functionality under the /rpc path
        if (!svr.start(80,eth)) {
            printf("Server not starting !\n");
            ethernetAvailable = false;
        } else {
            printf("Server listening (port %d)\n", PORT);
            printf("- LED1 flashes server heartbeat\n");
        }
    etc... 
    }


The following will give you an idea of my thinking on the HTTPServer class implementation. It seems to work, but my c++ is still minimal so possibly I still don't understand everything. In HTTPServer.h:

        bool start(int port = 80, EthernetInterface& eth = eth_init());
    private:
        /** create, initialise and connect a default EthernetInterface structure
        * if one is not passed into HTTPServer::start
        */
        static EthernetInterface& eth_init();


and in HTTPServer.cpp

EthernetInterface * eth_p;  // Pointer to eth structure passed into HTTPServer::start or created by default below.

// Function called by default parameter mechanism if user does not pass
// an EthernetInterface structure into HTTPServer::start.
EthernetInterface& HTTPServer::eth_init()
{
    EthernetInterface * eth_ptr = new EthernetInterface;
    INFO("Initializing network\n");
    eth_ptr->init();

    INFO("Connecting to network...");
    eth_ptr->connect();
    return  *eth_ptr;  
}

// Assume that if eth is passed, it has been initialised and connected.
bool HTTPServer::start(int port, EthernetInterface& eth)
{
    eth_p = &eth;
    INFO("Binding to port %d...", port);
    if (m_Svr.bind(port) < 0) {
        ERR("Failed to bind to port !\n");
        error("Binding");
        return false;
    }

    INFO("Listening ...");
 etc...


I am using a pointer "eth_p" to keep access to the eth structure, either default or from the user. However, I don't even see where you access the eth structure in your code after connecting, so I must be missing something. Still, it seems to work!

Cheers David.

posted by David Pairman 16 Aug 2013

Hi David,

returned from vacation (which was far too short). However, I think this may be a very common request to use the EthernetInterface for additional tasks (besides the HTTPServer). So I implemented an alternative way to use the HTTPServer. Using the latest Version of the HTTPServer you can provide an ethernetinterface object which you initialized and connected yourself and then finally just pass a pointer to the object to the HTTPServer's start function. This way you can get the ip address and perform your NTP request.

Hope this helps.

Cheers Henry.

posted by Henry Leinen 17 Aug 2013

Hi Henry,

That is great - thanks very much. I think you method has virtually the same effect as the approach I suggested. The only difference from the user’s perspective is that my approach passed the EhternetInterface object by reference to HTTPServer::start, whereas you pass a pointer to it. Both approaches generate a default object allocated from the heap if the user passes nothing.

I have updated to your latest version of HTTPServer. It still going unresponsive on the client side quite often. I'm only using the non-blocking mode and I haven’t tried it without the debug. Would those things have any impact, or have you confirmed that the problem is in the EthernetInterface code?

I’m out of town on business this week, so probably won’t get a chance to look at it again till next weekend.

Cheers

David.

posted by David Pairman 18 Aug 2013