5

I am trying to set up a websocket server using POCO 1.7.5.

The sample from POCO found here works well. Lines 111-122 reads (sligthly prettified):

WebSocket ws(request, response);
char buffer[1024];
int n, flags;

do
{
    n = ws.receiveFrame(buffer, sizeof(buffer), flags);
    ws.sendFrame(buffer, n, flags);
}
while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);

However, this approach does not take care of answering ping frames by pong frames. How do I do this properly using POCO? I tried the following, but I dont know if it is correct:

WebSocket ws(request, response);
char buffer[1024];
int n, flags;

do
{
    n = ws.receiveFrame(buffer, sizeof(buffer), flags);
    if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING){
        buffer[0] = WebSocket::FRAME_OP_PING;
        ws.sendFrame(buffer, 1, WebSocket::FRAME_OP_PONG);
    }
    else{
        ws.sendFrame(buffer, n, flags);
    }
}               
while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);

Dont know if this is the right way of doing it, and cannot find how to do it online, including the POCO documentation. The websocket RFC 6465 holds loads of info, but I dont want to go there, as I just want to use the websocket as an application programmer here

Community
  • 1
  • 1
Stefan Karlsson
  • 1,092
  • 9
  • 21

2 Answers2

7

From RFC you must send the same buffer with WebSocket::FRAME_OP_PONG flag. Try this:

do
{
    n = ws.receiveFrame(buffer, sizeof(buffer), flags);
    if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING) {
        ws.sendFrame(buffer, n, WebSocket::FRAME_OP_PONG);
    }
    else {
        ws.sendFrame(buffer, n, flags);
    }
}               
while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
Patricklaf
  • 306
  • 1
  • 6
  • Thinking about it, it seems to hold some logic to send the same buffer. Will give it a try within a day. Thanks – Stefan Karlsson Jan 27 '17 at 12:37
  • So now I read the rfc (6465), which turns out to be extremely easy as RFCs go (sections 5.5.2 and 5.5.3 deals with ping pong). If it is indeed this simple, then the POCO example should really be upgraded, and/or the webSocket function be upgraded to support doing this automatically (if so requested during initialization). If all goes well, will post on POCO forum and see what response i get. – Stefan Karlsson Jan 27 '17 at 15:02
  • 3
    Reponse PONG message should be send with additional `WebSocket::FRAME_FLAG_FIN`: `ws.sendFrame(buffer, n, WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PONG);` – JKovalsky May 29 '18 at 09:02
-1
do
{
    nbytes = ws->receiveFrame(buffer, sizeof(buffer), flags);
    if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING) {
        std::cout << "PING received\n";
        if (nbytes == 0) nbytes = 1; // Poco destroys active session if we send zero length string
        ws->sendFrame(buffer, nbytes, WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PONG);
        std::cout << " PONG sent\n";
        continue;
    }
    if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PONG) {
        std::cout << "PONG received\n";
        continue;
    }
    std::cout << nbytes << " bytes received from server:\n";

} while (nbytes > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
John
  • 1
  • 1