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)