FluidNC accepts commands over several interfaces. In addition to the usual USB serial port, you can also talk to FluidNC using raw TCP via the standard Telnet port 23 and the WebSocket protocol on port 81. The TCP port number can be configured with $Telnet/Port (default 23), while the WebSocket port number is one more than the HTTP port that is configured with $HTTP/Port (default 80, so the WebSocket port default is 81). FluidNC can accept commands over multiple interfaces simultaneously. For TCP/Telnet, it can also accept multiple simultaneous TCP connections from different clients.
For line-oriented commands, each interface collects a complete line before submitting it for processing. For character-oriented "realtime" commands, the character is handled as soon as it is received. Responses to commands sent over a channel are directed to the channel that sent the command. There are some system-generated messages that are not specific to one channel; such messages are broadcast to all currently-connected channels.
Regardless of which interface you are using, you must respect the GRBL protocol. You cannot just send as many commands as you wish at one time; you must inspect the FluidNC (GRBL protocol compatible) responses and use them to determine when the controller is ready to accept more data.
Here is some very simple (too simple) WebSocket code in Python. It illustrates the basics of opening a WebSocket connection, receiving/printing responses back from FluidNC, sending single-character (realtime) commands, and sending line-oriented commands. This simplified code does not implement the full protocol with respect to tracking ok and error responses and deciding when it is okay to send more. It just shows you the bare bones of pushing data through a WebSocket.
import threading, websocket
ws = websocket.WebSocket()
ws.connect("ws://192.168.68.125:81")
# Reception needs to be done in a separate thread; you cannot
# assume that a given command will always result in exactly one
# response at a predictable time
def receiver():
while True:
for l in ws.recv().splitlines():
if isinstance(l, str):
print(l)
else:
print(str(l, 'utf-8'))
t = threading.Thread(target=receiver)
t.start()
ws.send("?") # realtime characters need no line terminator
ws.send("$/axes/x\n") # line-oriented commands need \n at the end
WebUI uses the WebSocket interface for some of its communication with FluidNC (it also uses HTTP for some purposes). To see an example of WebSocket communication in JavaScript, you can browse the WebUI code.
When possible, choose WebSockets over TCP/Telnet. WebSockets is a newer protocol that solves some problems that make TCP/Telnet connections tricky to maintain.
WebUI uses the HTTP interface for various things like accessing files and sending some kinds of commands. HTTP is a single-request/single-response protocol whereby you send a request and get back a single answer. That is fine for some things, but inadequate for others. For example, if you want to run a GCode program from an SD card, you can start the run via HTTP and get an immediate response saying whether it started, but HTTP has no good way to report the ongoing progress later. WebUI uses a WebSocket for such ongoing messages.