Web servers form the foundation of the web, especially the Internet of Things (IoT).
Turning your phone or tablet into a web server or creating a network of interconnected devices is very simple with DroidScript.
Create a web server component using the CreateWebServer method of the app object:
wbs = app.CreateWebServer( port, options );
The following are valid options for the CreateWebServer method:
- "ListDir" - Show files in folder
- "Upload" - Allow file uploads
- "NoWelcome" - Ignore index.html
- "Reflect" - Reflect web socket messages back to all clients
Set a document root for the server using the SetFolder method of the WebServer object. This is the folder
location on your device that your web pages will be served from.
wbs.SetFolder( path );
Start the server using the Start method.
wbs.Start();
And stop it using the Stop method.
wbs.Stop();
The following example shows how to create a basic webserver for serving pages over WiFi from your device. It will serve a built in demo page.
For simplicity some of the features in the demo page will not work in this first example. Try them and you will see how the server presents errors. The next example shows how to handle all the features of the demo page.
Example
function OnStart()
{
var ip = app.GetIPAddress();
if( ip == "0.0.0.0" )
{
alert( "Please Enable Wi-Fi" );
app.Exit();
}
lay = app.CreateLayout( "linear", "VCenter,FillXY" );
var s = "Type the following address into your" +
" browser\n\n" + ip +":8080";
txt = app.CreateText( s, 0.8, 0.5, "MultiLine" );
txt.SetTextSize( 22 );
lay.AddChild( txt );
app.AddLayout( lay );
serv = app.CreateWebServer( 8080 );
serv.SetFolder( "/sdcard/DroidScript" );
serv.Start();
}
The second example shows how to accept file upload and permit directory listings by including permissions in the options parameter of the app.CreateWebServer method.
It also adds a servlet to respond to messsages from the web client. A servelet can be used to process data supplied by a user via form elements or it can handle requests made from the client application.
To get a better understanding of how client - server messaging works you can view the source of the served demo page and the network view in the developer tools of your favorite browser to see how the simple GET request is sent from the client browser to the servlet for processing by the OnServlet function when the Send Message button is clicked.
Example
function OnStart()
{
var ip = app.GetIPAddress();
if( ip == "0.0.0.0" )
{
alert( "Please Enable Wi-Fi" );
app.Exit();
}
lay = app.CreateLayout( "linear", "VCenter,FillXY" );
var s = "Type the following address into your" +
" browser\n\n" + ip +":8080";
txt = app.CreateText( s, 0.8, 0.5, "MultiLine" );
txt.SetTextSize( 22 );
lay.AddChild( txt );
app.AddLayout( lay );
serv = app.CreateWebServer( 8080, "Upload,ListDir" );
serv.SetFolder( "/sdcard/DroidScript" );
serv.AddServlet( "/message", OnServlet );
serv.Start();
}
function OnServlet( request, info )
{
serv.SetResponse( "Got it!" );
app.ShowPopup( info.remoteAddress + " says: " + request.msg );
}
Web sockets are faster than servlets and can be used for both client - server applications or peer-to-peer systems where each connected node is both a client and a server without a centralized server.
This makes web sockets very useful for datasharing in multiplayer games.
All requests sent to the same servlet will queue up behind each other and are processed in order. The server application is said to be blocking all other requests whilst a servlet completes each task synchronously.
Web sockets recieve the request and then start a process to handle the request. When the task is complete any data or messages to be returned will be sent back to the relevant connected clients. In this case the server application is said to be non-blocking or asynchronous.
Web sockets can be used for broadcast purposes, for example sending the same message to all connected clients. They can also be used to send different direct messages to a specific one device using the IP address.
The following example demonstrates web sockets being used to receive messages from and broadcasting messages to connected devices. It consists of two files.
Create a new App and call it WebSockets.
Create a new file called index.html in your application folder and copy the following code into it:
index.html
<html>
<head>
<title>WebSockets Demo</title>
<script>
var count = 0;
//Connect to server via web sockets.
function Connect()
{
//Check web sockets are supported.
if (!window.WebSocket)
{
alert("WebSocket not supported by this browser");
return;
}
//Open web socket to phone.
ws = new WebSocket( "ws://"+window.location.host );
ws.onopen = ws_onopen;
ws.onmessage = ws_onmessage;
ws.onclose = ws_onclose;
ws.onerror = ws_onerror;
}
//Send a message to the server.
function Send()
{
ws.send( "Hello " + count++ );
}
//Handle socket open.
function ws_onopen()
{
id_info.innerHTML = "Socket Open";
}
//Handle messages from phone.
function ws_onmessage( msg )
{
id_info.innerHTML = msg.data;
}
//Other websocket callbacks.
function ws_onclose()
{
id_info.innerHTML = "Socket Closed";
}
function ws_onerror(e)
{
id_info.innerHTML = "Socket Error: " + e.data;
}
</script>
</head>
<body>
<h2>DroidScript WebSockets Demo</h2>
<div id="id_info">Ready</div>
<button onclick="Connect()">Connect</button>
<button onclick="Send()">Send Message</button>
</body>
</html>
Copy the following code into your main WebSockets.js application file.
WebSockets.js
// Init variables.
var count = 0;
// Called when application is started.
function OnStart()
{
// Check wifi is enabled.
ip = app.GetIPAddress();
if( ip == "0.0.0.0" ) {
app.ShowPopup( "Please Enable Wi-Fi" );
app.Exit();
}
// Prevent wifi from powering down.
app.PreventWifiSleep();
// Create a layout with objects vertically centered.
lay = app.CreateLayout( "linear", "VCenter,FillXY" );
// Create a text label and add it to layout.
var s = "Type the following address into your" +
" browser(s)\n\n" + ip +":8080";
txt = app.CreateText( s, 0.8, 0.3, "AutoScale,MultiLine" );
txt.SetTextSize( 22 );
lay.AddChild( txt );
// Create a text label and add it to layout.
txtMsg = app.CreateText( "", 0.8, 0.3, "AutoScale,MultiLine" );
txtMsg.SetTextSize( 22 );
lay.AddChild( txtMsg );
// Create a 'Send Message' button.
btn = app.CreateButton( "Send Message", 0.4, 0.1);
btn.SetMargins( 0, 0.05, 0, 0 );
btn.SetOnTouch( SendMessage );
lay.AddChild( btn );
// Add layout to app.
app.AddLayout( lay );
// Create and run web server on port 8080.
serv = app.CreateWebServer( 8080 );
serv.SetFolder( "/sdcard/DroidScript/WebSockets" );
serv.SetOnReceive( serv_OnReceive );
serv.Start();
// Start timer to show WebSock connections.
setInterval( ShowConnections, 3000 );
}
// Show who is connected.
function ShowConnections()
{
var clients = serv.GetWebSockClients();
if( clients.length > 0 )
{
// Make a list of clients.
var list = "";
for( var i=0; i < clients.length; i++ )
{
list += clients[i].remoteAddress + "\n";
}
// Show client list.
txt.SetText( list );
}
}
// Send a message to all connected socket clients.
function SendMessage()
{
// Note: You can send to a specific client by passing
// the IP address as the second parameter.
serv.SendText( "Hello " + count++ )
}
// Called when messages arrive from websocket clients.
function serv_OnReceive( msg, ip )
{
txtMsg.SetText( ip + ": " + msg );
}
See 'CreateWebServer for more informations and a complete function list