May 282016
 
nodemcu and web- or not-web-sockets

Got one of those neat ESP8266 modules with nodemcu and eLua on it. Running a web server is not recommended due to the limited amount of memory it has. The goal today was to make an LED on/off via a web page. A TCP socket would do fine (UDP too). Browser cannot (yet) use normal sockets, so websockets it is. Easy decision.

Found a library for nodemcu to do websockets but that did not work with the websocket clients I tried (Dark WebSocket Terminal among others): I could connect, but data never was sent. Wireshark confirmed that no data flows to the websocket listener. The opening and closing sequence seems to work fine. I have no idea what is missing, but since no actual data was sent at all and there was no other websocket implementation for nodemcu, I used TCP sockets on the ESP8266 side. That worked immediately.

But to make browser work with this, I need a websocket-to-tcp bridge. Which works just fine. The advantage is that the ESP8266 can connect as a client to a TCP socket on a gateway server on the Internet, and the client software can connect via websockets to that same server, which neatly works around NAT’ing routers.

So here I present all 2 pieces. The Lua part running on the ESP8266 (Pin 4 is a LED which turns on when you write LOW to the pin):

gpio.mode(4, gpio.OUTPUT)
led4=gpio.LOW

srv=net.createServer(net.TCP)
srv:listen(9001, function(conn)
  conn:on("receive", function(conn, payload)
    gpio.write(4, led4)
    led4=(led4==gpio.LOW) and gpio.HIGH or gpio.LOW
    -- print(payload)
    conn:send("ok\r\n")
    end)
  end)

and here the call for the websocket to TCP bridge:

./ws-tcp-bridge --lport 9000 --rhost 192.168.21.208:9001 --method ws2tcp

where port 9000 on the local host is where the websocket listener listens, and 192.168.21.208:9001 is the TCP listener on the ESP8266.

And that’s it. Now when connecting via e.g. Dark Websocket Terminal to 127.0.0.1:9000, and sending anything, the LED4 will change its state.

 

Next step: have a JavaScript front-end. DroidScript it’ll be. Then maybe a web page via node.js.