Exemple #1
0
/*
    Event callback. Invoked for incoming web socket messages and other events of interest.
    We're interested in the WRITABLE event.
 */
static void output_callback(HttpConn *conn, int event, int arg)
{
    Output      *output;
    ssize       len, wrote;
    int         flags, type;
    char        buf[MPR_BUFSIZE];

    /*
        Get a writable event when the socket can absorb more data
     */
    if (event == HTTP_EVENT_WRITABLE) {
        output = getData();
        do {
            if ((len = mprReadFile(output->file, buf, sizeof(buf))) > 0) {

                /*
                    Set the HTTP_MORE flag on every write except the last. This means each write is sent as
                    a separate frame. The first frame has the type of WS_MSG_TEXT, all others must be 
                    continuation frames.
                 */
                flags = HTTP_NON_BLOCK;
                if ((output->written + len) < output->info.size) {
                    flags |= HTTP_MORE;
                }
                type = output->written == 0 ? WS_MSG_TEXT : WS_MSG_CONT;
                /*
                    Send the next chunk as a WebSockets frame using a non-blocking write. 
                    This may return having written only a portion of the requested data.
                 */
                if ((wrote = httpSendBlock(conn, type, buf, len, flags)) < 0) {
                    httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot send message of %d bytes", len);
                    return;
                }
                output->written += wrote;
                if (wrote < len) {
                    /* Reposition if the send returned having written less than requested */
                    mprSeekFile(output->file, SEEK_CUR, wrote - len);
                    break;
                }
            } else {
                httpSendClose(conn, WS_STATUS_OK, "OK");
                break;
            }
        } while (len > 0);

    } else if (event == HTTP_EVENT_APP_CLOSE) {
        mprLog(0, "output.c: close event. Status status %d, orderly closed %d, reason %s", arg,
        httpWebSocketOrderlyClosed(conn), httpGetWebSocketCloseReason(conn));

    } else if (event == HTTP_EVENT_ERROR) {
        mprLog(0, "output.c: error event");
    }
}
Exemple #2
0
static void traceEvent(HttpConn *conn, int event, int arg)
{
    HttpPacket  *packet;

    if (event == HTTP_EVENT_READABLE) {
        packet = conn->readq->first;
        mprLog(3, "websock.c: read %s event, last %d", packet->type == WS_MSG_TEXT ? "text" : "binary", packet->last);
        mprLog(3, "websock.c: read: (start of data only) \"%s\"", snclone(mprGetBufStart(packet->content), 40));

    } else if (event == HTTP_EVENT_APP_CLOSE) {
        mprLog(3, "websock.c: close event. Status status %d, orderly closed %d, reason %s", arg,
               httpWebSocketOrderlyClosed(conn), httpGetWebSocketCloseReason(conn));

    } else if (event == HTTP_EVENT_ERROR) {
        mprLog(2, "websock.c: error event");
    }
}
Exemple #3
0
/*
    Event callback. Invoked for incoming web socket messages and other events of interest.
 */
static void echo_callback(HttpConn *conn, int event, int arg)
{
    HttpPacket      *packet;

    if (event == HTTP_EVENT_READABLE) {
        /*
            Grab the packet off the read queue.
         */
        packet = httpGetPacket(conn->readq);
        if (packet->type == WS_MSG_TEXT || packet->type == WS_MSG_BINARY) {
            /*
                Echo back the contents
             */
            httpSendBlock(conn, packet->type, httpGetPacketStart(packet), httpGetPacketLength(packet), 0);
        }
    } else if (event == HTTP_EVENT_APP_CLOSE) {
        mprLog("info echo", 0, "close event. Status status %d, orderly closed %d, reason %s", arg,
        httpWebSocketOrderlyClosed(conn), httpGetWebSocketCloseReason(conn));

    } else if (event == HTTP_EVENT_ERROR) {
        mprLog("info echo", 0, "error event");
    }
}