Web server
Posted: 19 Sep 2015, 22:02
LuaMacros (from version 0.1.0.220) have embedded simple 1-thread web server. Any request for this server can be handled in Lua code and therefore trigger another action. Typical usage would be for flight simulation when you prepare some nice looking web page with plane's panel and by clicks in this panel you control your plane in simulator. The web page can be opened not only at local computer but also from different computer connected through network, tablet, phone...
Let's see how to do this in code. The simplest web server started at port 12345 would be
After running this code you can open web browser and enter e.g. http://localhost:12345/sayHi
The output in LuaMacros console would be "Callback for /sayHi".
Let's do something more useful with flight simulation example.
Have this code:
And simple html page:
With this page you can control your beacon light in Xplane simulator!
Now let's make the LUA code more universal. You can forward any command to Xplane simulator. Consider any request starting with /command/ as Xplane command:
Then change your html page to
And with simple LUA code you can send any command from the web page!
There's more. The web page doesn't work well now. And I don't mean it doesn't have very nice background image and links displayed as buttons at light panel. The problem is you click the link and end up at page generated by LuaMacros application which shows just OK. You don't see you nice panel any more. If you are html developer you don't care and convert links to some modern AJAX calls. If you're not you just add "/back" at the beginning of your links. Now LuaMacros recognizes the "/back" at the beginning and use it internally. It means the "/back" won't arrive into your LUA code. You don't need to change the code. What LuaMacros application does is it won't generate just "OK" result page but page which will hit Back button of your browser via JavaScript. So you will end up at your original page with panel. So try this html code:
There's even more. Without the "/back" feature LuaMacros return just boring "OK" as response. But wait, LuaMacros can also read data from the simulator. So maybe with some small web development your panel could even show if your taxi lights or beacon is on or off. Maybe it could display frequency of your radios. So why you don't read frequency of ADF in LuaMacros and don't return it instead of that boring OK? Then you can read the response and adapt you panel accordingly. The LUA code would be for example:
Then request http://localhost:12345/getADF won't return OK but the frequency you have in your plane's ADF now. And the script can be changed to something more usable:
and request could be http://localhost:12345/get/sim/cockpit/ ... f1_freq_hz
One more thing: I didn't forget you, web developers with AJAX calls and perfect panels. Return second argument from web server handler and you can set the content type. Something like:
Let's see how to do this in code. The simplest web server started at port 12345 would be
Code: Select all
lmc_http_server(12345, function(url)
print('Callback for ' .. url)
end)
The output in LuaMacros console would be "Callback for /sayHi".
Let's do something more useful with flight simulation example.
Have this code:
Code: Select all
lmc_http_server(12345, function(url)
if url == '/beacon_on' then
lmc_xpl_command('sim/lights/beacon_lights_on')
elseif url == '/beacon_off' then
lmc_xpl_command('sim/lights/beacon_lights_off')
else
print('Callback for ' .. url)
end
end)
Code: Select all
<html>
<a href="http://localhost:12345/beacon_on">Beacon on</a>
<a href="http://localhost:12345/beacon_off">Beacon off</a>
</html>
Now let's make the LUA code more universal. You can forward any command to Xplane simulator. Consider any request starting with /command/ as Xplane command:
Code: Select all
lmc_http_server(12345, function(url)
if url:match("^/command/.+") then
lmc_xpl_command(url:sub(10))
else
print('Unknown request ' .. url)
end
end)
Code: Select all
<html>
<a href="http://localhost:12345/command/sim/lights/beacon_lights_on">Beacon on</a>
<a href="http://localhost:12345/command/sim/lights/beacon_lights_off">Beacon off</a>
<a href="http://localhost:12345/command/sim/lights/taxi_lights_on">Taxi on</a>
<a href="http://localhost:12345/command/sim/lights/taxi_lights_off">Taxi off</a>
</html>
There's more. The web page doesn't work well now. And I don't mean it doesn't have very nice background image and links displayed as buttons at light panel. The problem is you click the link and end up at page generated by LuaMacros application which shows just OK. You don't see you nice panel any more. If you are html developer you don't care and convert links to some modern AJAX calls. If you're not you just add "/back" at the beginning of your links. Now LuaMacros recognizes the "/back" at the beginning and use it internally. It means the "/back" won't arrive into your LUA code. You don't need to change the code. What LuaMacros application does is it won't generate just "OK" result page but page which will hit Back button of your browser via JavaScript. So you will end up at your original page with panel. So try this html code:
Code: Select all
<html>
<a href="http://localhost:12345/back/command/sim/lights/beacon_lights_on">Beacon on</a>
<a href="http://localhost:12345/back/command/sim/lights/beacon_lights_off">Beacon off</a>
<a href="http://localhost:12345/back/command/sim/lights/taxi_lights_on">Taxi on</a>
<a href="http://localhost:12345/back/command/sim/lights/taxi_lights_off">Taxi off</a>
</html>
Code: Select all
lmc_http_server(12345, function(url)
if url == '/getADF' then
return lmc_get_xpl_variable('sim/cockpit/radios/adf1_freq_hz')
else
print('Unknown request ' .. url)
end
end)
Code: Select all
lmc_http_server(12345, function(url)
if url:match("^/command/.+") then
lmc_xpl_command(url:sub(10))
elseif url:match("^/get/.+") then
return lmc_get_xpl_variable(url:sub(6))
else
print('Unknown request ' .. url)
end
end)
One more thing: I didn't forget you, web developers with AJAX calls and perfect panels. Return second argument from web server handler and you can set the content type. Something like:
Code: Select all
return '{"HDG" : 123}', 'application/json'