Callback style API on socket connection readable in R

Viewed 42

I have an R script which consumes a feed periodically and then produces signals or actions, which need to be sent to a TCP server implemented in other language. I have handled the signal generation part in this fashion:

sendViaSocket <- function(object, socket) {
    byteLen <- as.integer(object$byteLen())

    writeBin(
        byteLen, socket,
        endian = "little",
        useBytes = TRUE
    )
    writeBin(
        object$toRaw(), socket,
        useBytes = TRUE
    )
}

readFromSocket <- function(socket) {
    packetLen <- readBin (
        socket, integer(), endian = "little"
    )

    rawVec <- readBin(
        socket, "raw", n = packetLen
    )

    return (
        parse (messages.MyMessage, rawVec)
    )
}

getOHLC <- function() {
    # feed reading function
    ...
}

generateSignal <- function (candleStick) {
    # signal generating function
    ...
}

performAction <- function(message) {
    # Action on server message
}

clientLoop <- function() {
    socket <- socketConnection(
        host = 'localhost',
        port = 42000,
        blocking = TRUE,
        server = FALSE,
        open = "a+b"
    )

    while(TRUE) {
        candleStick <- getOHLC()

        signal <- generateSignal(candleStick)

        sendViaSocket(signal, socket)

        # Reading any message from server
        object <- readFromSocket(message)

        Sys.sleep(10)
    }
}

clientLoop()

I have deliberately set the socket connection as blocking as I want to read all the data available in the connection in one go, and send message in one go.

Currently I am reading any notification from client loop itself, but if the server does not send anything, the client loop is blocked.

What I want to do is have a callback when the socket has received any data, and then process that data in the callback. This will not block the client loop. Something along the following lines

onServerDataReceived <- function (serverMessage) {
    # Perform related action on receiving server message
}

socket$onDataReceived(callback = onServerDataReceived)

Is there a way in which I can use a client socket connection with a callback when the server actually sends a message/ or do this in a reactive / asynchronous way?

Edit: As a bonus I also don't want to do while (TRUE) {...} and use an API or package that provides a better way to call the clientLoop() function periodically every n seconds (minimum interval is 30 seconds)

0 Answers
Related