ComputerCraft icon indicating copy to clipboard operation
ComputerCraft copied to clipboard

Websocket support

Open SquidDev opened this issue 7 years ago • 2 comments

This uses Netty's websocket functionality, meaning we do not have to depend on another library.

API

As websockets do not fit neatly into the standard polling socket model, the API is significantly more event based than CCTweaks's. One uses http.websocket to connect, which will wait until a connection is established and then returns the connection object (an async variant is available).

Once you have a websocket object, you can use .send(msg) to transmit a message. Incoming messages will fire a "websocket_message" event, with the URL and content as arguments. A convenience method (.receive()) exists to aid waiting for valid messages.

A websocket_closed event is also fired if the server forcibly terminates the connection, or it times out.

I'd really appreciate feedback on this - I'm not entirely sure it's the best approach, but IMO it's neater than CCTweaks's.

Example

local res, err = http.websocket("wss://echo.websocket.org")
if not res then error(err, 0) end

for i = 1, 10 do
    res.send("hello " .. i)
    print(res.receive())
end

res.close()

Possible enhancements

These are things which probably should be implemented at some point, but I'm looking for some thoughts on them first. Not all of them are entirely websocket related.

  • Limit the number of open sockets. I think it is worth discussing how we can best limit both the number of open sockets and the number of active HTTP requests. It should be relatively trivial to handle either.
  • Automatically close the socket when it is GCd, like we do for file handles. We'd probably have to split up the connection into the ILuaObject part and the socket holding part, detecting when the former is no longer referenced.
  • Have a separate blacklist (and whitelist?) for websockets. There may be some sites for which one would like to allow simple requests, but not websockets.
  • Add a timeout argument to receive(). I'm not sure the best way to go about that - we obviously don't have access to os.startTimer on the Java side.
  • Replace the current HTTP code with netty's. This means we can do it all asynchronously, and so not consume a thread for each request.

Closes #161

SquidDev avatar Jul 30 '17 17:07 SquidDev

The API description which you gave at the start of your post sounds like it mimics the rednet/modem API's in interface, which I would consider a plus as that is what some users of the mod will be more familiar with when using the API.

Lupus590 avatar Jul 30 '17 17:07 Lupus590

I made what I believe to be the first public software to use this PR. It makes a file handle interface to the WebsocketConnection object.

MineRobber9000 avatar Sep 24 '17 23:09 MineRobber9000