Skip to content

kamahen/swipl-server-js-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple SWI-Prolog - Javascript client/server

A simple example of a SWI-Prolog server and a Javascript client.

See also: https://www.swi-prolog.org/howto/http/

License

Simplified BSD

Javascript/ECMAScript

“We are tied down to a language which makes up in obscurity what it lacks in style.”
— Tom Stoppard, Rosencrantz and Guildenstern are Dead

1995 — Brendan Eich reads up on every mistake ever made in designing a programming language, invents a few more, and creates LiveScript. Later, in an effort to cash in on the popularity of Java the language is renamed JavaScript. Later still, in an effort to cash in on the popularity of skin diseases the language is renamed ECMAScript.
A Brief, Incomplete, and Mostly Wrong History of Programming Languages

Warning

This code is an overly simple example of client-server code, intended as a tutorial or to extend the HTTP support documentation in the SWI-Prolog manual and the tutorial at http://www.pathwayslms.com/swipltuts/html.

The example code sends a query to the server, which executes it and returns the result. Obviously, this is a dangerous thing to do without proper sand-boxing, but it's useful for tutorial purposes. (In other words, don't run this server anywhere that someone from the "outside" can access it.)

The code has only been tested with a recent "development" release of SWI-Prolog (8.3.7) on Ubuntu 18.0.4 and with the Chrome browser. The server has been reported to run under Windows 10 from the DOS prompt, with the client on Microsoft Edge browser.

How to run

Install SWI-Prolog development version.

For Ubuntu, Debian, and similar (following the instructions at https://www.swi-prolog.org/build/PPA.html), use these steps:

  • sudo apt install software-properties-common
  • sudo apt-add-repository ppa:swi-prolog/devel
  • sudo apt update
  • sudo apt install swi-prolog

Start the server:

swipl simple_server.pl --port=9999 --staticdir=static

In a browser, start the client: http://localhost:9999.

You might try this query:

get_time(TimeStamp), stamp_date_time(TimeStamp, DateTime, local), bagof(Key-Value, date_time_value(Key, DateTime, Value), DatePieces), dict_create(DateDict, date, DatePieces)

or this:

setof(K:V,current_prolog_flag(K,V), Flags), forall(member(K:V, Flags), format('~|~q:~t~40+~q~n', [K,V]))

To stop the server, enter the line

halt.

or ctrl-D (possibly ctrl-Z on Windows).

Here's an example of a query and response, at the HTTP level, using nc as the client:

(echo 'POST /json HTTP/1.1';
 echo 'Host: localhost:9999';
 echo 'Content-Length: 18';
 echo 'Content-Type: application/json'
 echo 'Accept: */*'
 echo 'Origin: http://localhost:9999';
 echo ''
 echo -n '{"query":"X = 1."}'
) | nc -C -N localhost 9999

which produces this output (from nc):

HTTP/1.1 200 OK
Date: Wed, 20 Apr 2022 21:01:42 GMT
Connection: Keep-Alive
Content-Type: application/json
Content-Length: 131

{"error":"", "printed_output":"", "query":"X = 1.", "query_after_call":"1=1", "success":true, "vars": [ {"value":"1", "var":"X"} ]}

Code overview

There are three client components and one server component:

  • static/simple_client.html
  • static/simple_client.css
  • static/simple_client.js
  • simple_server.pl

If the server is accessed at the top level ("/"), the http_handler for root(.) does a redirect to static('simple_client.html'), which causes the browser to fetch that HTML (using the server). All other static files are accessed by the same mechanism.

  • The HTML path static('simple_client.html') is resolved using http:location/2 facts - see the comments there.

  • static_dir('simple_client.html') is resolved using file_search_path/2. During server start-up, assert_server_locations/1 is called to asserta a file_search_path fact to redirect static(Path) to the directory specified by the option --staticdir).

The simple_client.html file has this line in its <head>:

<script src="simple_client.js" defer="defer"></script>

which contains a function renderPage(), which is invoked by:

<body onload="renderPage();">

(The simple_client.js code is fetched from the server, using the http_handler/3 for static(.), which in turn uses http_reply_from_files/2 (in library(http/http_files) to do the work.)

The JavaScript code in the client communicates with the server using the fetchFromServer function, which sends a stringified JSON data structure containing the request and sets a callback for processing the result (which is also a JSON-encoded data structure).

On the server, the http_handler for root(json) (/json) calls reply_with_json/1, which deserializes the JSON request and calls json_response/2 to deal with the specific request.

Miscellaneous

The favico.ico is taken from http://swi-prolog.org.

About

Sample SWI-Prolog server with JavaScript client

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published