5

I am trying to connect to a socket.io socket in R using the R function socketConnection(). However, although I am able to set up the socket properly, I am not able to read data from it into R.

The javascript code I use to set up the server is:

var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');

app.listen(8005);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.on('connection', function (socket) {
  setInterval(function() {
    socket.emit('update', "test")
  }, 1000);
});

The code for index.html is:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://localhost:8005');
  socket.on('update', function (data) {
    console.log(data);
  });
</script>

I am able to verify that the socket is indeed working by going to localhost:8005 in my web browser and opening up the Developer's Console, where I can see "test" being logged. However, when I try to connect to the socket in R by:

sock <- socketConnection("localhost", 8005, blocking = FALSE, open = "r")
readLines(sock)

Every time I run readLines(sock) I get an empty character vector back. I have also confirmed I can read from other sockets in R by executing the following and indeed getting a response from readLines(sock):

sock <- socketConnection("rstudio.com", 6789, blocking = FALSE, open = "r")
readLines(sock)

Any help would be greatly appreciated. Thanks!

UPDATE (2015-09-01):

Thanks to the excellent help from Aaron Dufour, I was able to adapt this net server demo to stream data into R. The javascript code I used for the server was

var net = require('net');

var server = net.createServer(function(socket) {
    setInterval(function() {
        socket.write('Test\r\n');
        socket.pipe(socket);
    }, 1000)
});

server.listen(1337, '127.0.0.1');

And the R code was:

sock <- socketConnection("localhost", 1337, open = "r")
readLines(sock)
close(sock)

I did get the following warning warning: possible EventEmitter memory leak detected. 11 end listeners added. Use emitter.setMaxListeners() to increase limit. sometimes on the server side when I ran readLines(socket)

Also, when I ran close(socket) in R the server crashed and I get the following error: Error: This socket has been ended by the other party

With additional research, I think both the warning and error are preventable.

jeromefroe
  • 1,345
  • 12
  • 19

1 Answers1

2

As I've described here, the socket.io protocol is much more than a WebSocket. Just opening a WebSocket to it won't work.

But socketConnection appears to not even be a WebSocket, but rather a raw socket. You're getting nothing back because the server is talking HTTP and you haven't finished sending an HTTP request.

You probably need a socket.io library for R, or to switch away from socket.io on the server.

Community
  • 1
  • 1
Aaron Dufour
  • 17,288
  • 1
  • 47
  • 69
  • 1
    Thanks for the help! I did some more research into socket.io clients, and found the python library [socketIO-client](https://github.com/invisibleroads/socketIO-client) with which I was able to connect to socket.io and receive the data in python. I think I may look into the source code to try and do the same thing in R. Alternatively, there is an npm module [raw-socket](https://www.npmjs.com/package/raw-socket) for implementing raw sockets, which could potentially replace socket.io on the server like you suggested. – jeromefroe Aug 29 '15 at 16:53
  • 1
    @JeromeFroelich If you're using TCP, you can use the [net](https://nodejs.org/api/net.html#net_net) module, which is built in. – Aaron Dufour Aug 30 '15 at 16:05
  • 1
    thanks, you were exactly right! I was able to set up a server with `net`, and use R's `socketConnection` function to read the data. I think my next step is to do some more research into `net` to make the server more robust to potential errors. Thanks again for the help! – jeromefroe Aug 31 '15 at 23:48