Using a remote Raspberry Pi's OS by Node.js
See Using a remote PC's Windows OS by Node.js. We have tested this in November 2019 with Version 9.15.0 of Node on a Model B Raspberry Pi with the latest Debian OS flashed to it. Remember to change the URL of the client to that of your Pi on the local network (e.g. 192.168.1.4) and test it with commands such as node -v, ifconfig and ls.
Using a remote Raspberry Pi's OS by Node.js using early versions of Smart Mobile Studio
This Smart Pascal program, inspired by James's remote control of the Raspberry Pi, uses Node.js to execute commands on the Raspberry Pi. It has a similar set-up to that described in detail on the previous page. As with the PHP version, the user has the choice of selecting one of the tested commands in the combo box or typing a command into the edit box.
The Smart Pascal code of the server and client and the XML code of the form follow the screenshot of the program in action.

Application in Action
Smart Pascal Code of Server
You can compare this code with a JavaScript version.
unit Unit1; interface type TServer = class public procedure Run; end; implementation uses NodeJS.Core, NodeJS.http, Node_Static, socket.io; procedure TServer.Run; begin var fileserver := TNodeStaticServer.Create('./public'); //start http server var server: JServer := http.createServer( procedure(request: JServerRequest; response: JServerResponse) begin Console.log('http request: ' + request.url); if request.url = '/' then request.url := '/PiClientExec.html'; fileserver.serve(request, response); end); server.listen(8079, ''); Console.log('Server running at http://192.168.0.6:8079'); var value := 0; var io := socketio().listen(server); io.sockets.on('connection', // waiting for connections procedure(socket: JSocketIO) begin socket.on('requestFromClient', // waiting for a special request from the client procedure(data: Variant; callback: JSocketIODataFunction) begin Console.log('Received from client: ' + data); asm var exec = require('child_process').exec; exec(data, function(err, stdout, stderr) { if (err) { @callback('error code ' + err.code); return; } @callback(stdout); }); end; end); end); end; end.
Smart Pascal Code of Form of Client
unit Form1; interface uses SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button, SmartCL.Controls.Panel, SmartCL.Controls.EditBox, SmartCL.Controls.Memo, socketioclient, SmartCL.Controls.ComboBox; type TForm1 = class(TW3Form) procedure W3Button1Click(Sender: TObject); private FSocket: JSocketIO; {$I 'Form1:intf'} protected procedure InitializeObject; override; end; implementation procedure TForm1.W3Button1Click(Sender: TObject); begin FSocket.emit('requestFromClient', [W3EditBox1.Text], procedure(aData: variant) begin W3Memo1.Text := aData; end); end; procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} FSocket := socketio.connect('http://192.168.0.6:8079'); W3Combobox1.Add('echo This is fun!'); W3Combobox1.Add('pwd'); W3Combobox1.Add('ls'); W3Combobox1.Add('du -h'); W3Combobox1.Add('uname -a'); W3Combobox1.Add('date'); W3Combobox1.Add('cal 8 2015'); W3Combobox1.Add('grep "html" index.html'); W3Combobox1.OnClick := procedure(Sender: TObject) begin FSocket.emit('requestFromClient', [W3Combobox1.Items[W3Combobox1.SelectedIndex]], procedure(aData: variant) begin W3Memo1.Text := aData; end); end; end; initialization Forms.RegisterForm({$I %FILE%}, TForm1); end.
XML Code of Form
<SMART> <Form version="2" subversion="1"> <Created>2015-10-09T13:46:42.361</Created> <Modified>2015-10-09T19:28:06.278</Modified> <object type="TW3Form"> <Caption>W3Form</Caption> <Name>Form1</Name> <object type="TW3Panel"> <Width>536</Width> <Top>16</Top> <Height>320</Height> <Name>W3Panel1</Name> <object type="TW3Button"> <Caption>Send command</Caption> <Width>128</Width> <Top>30</Top> <Left>160</Left> <Height>32</Height> <Name>W3Button1</Name> <OnClick>W3Button1Click</OnClick> </object> <object type="TW3EditBox"> <Value></Value> <Text>ls -lh</Text> <Range></Range> <Width>128</Width> <Top>30</Top> <Left>24</Left> <Height>32</Height> <Name>W3EditBox1</Name> </object> <object type="TW3Memo"> <Text>W3Memo</Text> <Width>488</Width> <Top>80</Top> <Left>24</Left> <Height>216</Height> <Name>W3Memo1</Name> </object> <object type="TW3ComboBox"> <Width>168</Width> <Top>32</Top> <Left>336</Left> <Height>32</Height> <Name>W3ComboBox1</Name> </object> </object> </object> </Form> </SMART>