# Interfacing with Angular

**URL:** <https://swi-prolog.discourse.group/t/interfacing-with-angular/2722>\
**Category:** Help!\
**Created:** [July 30, 2020, 12:19pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722 "2020-07-30T12:19:02Z")\
**Posts on this page:** 17\
**Page:** 2

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 14, 2020, 8:39am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/24 "2020-08-14T08:39:47Z")

</div>

Agree. Websockets have benefits especially when server _push_ is required or to reduce latency. They also come at a price. It is an open connection that easily breaks on some network issue and requires support in proxy servers. That is more readily available these days, but still not always guaranteed ☹

A good use case is probably using a browser as GUI for an application on the same host or in a LAN, so connection issues are irrelevant and latency really goes down to the sub-millisec range.

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [August 14, 2020, 10:31am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/25 "2020-08-14T10:31:38Z")

</div>

> [@jan](#):
>
> This is a bit old. New code better use `library(http/http_dyn_workers)` or load all server basics using `library(http/http_server)` .

I’m a bit lost here. Do I simply add this library to the list as in

> [@joeblog](#):
>
> ```prolog
> :- use_module(library(http/websocket)).
> :- use_module(library(http/http_server)).
> :- use_module(library(http/http_unix_daemon)).
> 
> ```

and then simply shorten the command to start the server to

```bash
swipl server.pl --port=6455 --pidfile=http.pid

```

or do I need to add anything else to the Prolog script?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 14, 2020, 10:46am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/26 "2020-08-14T10:46:32Z")

</div>

That is just fine. The `http_server.pl` library loads a reasonable part of the server architecture that just about any server needs. This avoid having to remember all the basic server libraries. Add what is missing (in this case websockets and the Unix daemon infrastructure) and you’re ready to go.

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [August 15, 2020, 2:05pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/27 "2020-08-15T14:05:37Z")

</div>

After several hours of trying to get wss:// and nginx to play nicely, I’ve conceded defeat and got JavaScript in the browser and SWI Prolog server to communicate via JSON like so:

```prolog
:- use_module(library(http/http_server)).
:- use_module(library(http/http_files)).
:- use_module(library(http/http_unix_daemon)).

:- initialization http_daemon.

:- http_handler(root(.), http_reply_from_files('.', [indexes(['./index.html'])]), [prefix]).
:- http_handler(root(prolog), prolog_handler, []).

prolog_handler(Request) :-
  http_read_json_dict(Request, DictIn),
  request_handler(DictIn.request, DictIn, DictOut),
  reply_json_dict(DictOut).

request_handler("ping", _Dict, json{reply: pong}).

```

Browser code:

```javascript
function prologServer(Request) {
  return fetch("prolog",
  { method: "POST"
  , headers: { "Content-Type": "application/json"}
  , body: JSON.stringify(Request)
  }
);
}

prologServer({"request": "ping"})
.then(response => response.json())
.then(data => document.querySelector("#message").innerText = data.reply);

```

The next interesting question is how to format the Json values so that Prolog and Javascript can use it as a lingua franca.

Using the introductory example from Bratko as an example by initial thought is if the Prolog looks like:

```prolog
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, pat).
parent(pat, jim).

```

Then the Json should be

```json
[["parent", "pam", "bob"],
  ["parent", "tom", "bob"],
  ["parent", "tom", "liz"],
  ["parent", "bob", "pat"],
  ["parent", "pat", "jim"]
]

```

which the Prolog script could then iteratively translate with [**term\_string** (?Term, ?String)](https://www.swi-prolog.org/pldoc/doc_for?object=term_string/2) and then `Term =.. List` to translate, and then do the reverse in the reply to the browser.

Though not difficult, I wondered if there’s already a convention and libraries to do this?

---

<div class="post-metadata">

**Author:** ![torbjorn.lager](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/torbjorn.lager/32/7890_2.png) [@torbjorn.lager](https://swi-prolog.discourse.group/u/torbjorn.lager)\
**Post date:** [August 15, 2020, 4:42pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/28 "2020-08-15T16:42:14Z")

</div>

Not sure if it covers all your need, but check out this library:

[https://www.swi-prolog.org/pldoc/man?section=termtojson](https://www.swi-prolog.org/pldoc/man?section=termtojson)

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [August 15, 2020, 6:20pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/29 "2020-08-15T18:20:41Z")

</div>

Thanks @torbjorn.lager

I managed to get what I wanted:

```prolog
?- json_prolog([["parent", "pam", "bob"],["parent", "tom", "bob"],["parent", "tom", "liz"], ["parent", "bob", "pat"],["parent", "pat", "jim"]], Terms).
Terms = [parent(pam, bob), parent(tom, bob), parent(tom, liz), parent(bob, pat), parent(pat, jim)].

?- json_prolog(L, [parent(pam, bob), parent(tom, bob), parent(tom, liz), parent(bob, pat), parent(pat, jim)]).
L = [["parent", "pam", "bob"], ["parent", "tom", "bob"], ["parent", "tom", "liz"], ["parent", "bob", "pat"], ["parent", "pat", "jim"]].

```

With the little module below. Making this bidirectional was a bit of a hack, but it works. I might need to make it more elaborate to handle nested lists/compounds, but this is all I need for now:

```prolog
:- module(json_prolog, [json_prolog/2]).

unquote_quote(Unquoted, Quoted) :-
  maplist(term_string, Unquoted, Quoted).

json_prolog(QLists, PrologList) :-
  nonvar(QLists), var(PrologList), !,
  maplist(unquote_quote, UQLists, QLists),
  maplist(=.., PrologList, UQLists).

json_prolog(QLists, PrologList) :-
  var(QLists), nonvar(PrologList), !,
  maplist(=.., PrologList, UQLists),
  maplist(unquote_quote, UQLists, QLists).

```

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 15, 2020, 6:22pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/30 "2020-08-15T18:22:37Z")

</div>

I have some code that uses “bare” JavaScript (using `WindowOrWorkerGlobalScope.fetch()`) and a simple Prolog server using `http_handler` and `http_read_json_dict`. If anyone is interested, I can excerpt a simple code example (it’ll take me a few hours; but the code needs some refactoring anyway).

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 17, 2020, 10:25am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/31 "2020-08-17T10:25:59Z")

</div>

It would be nice to have a simple self-contained example code for that.

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [August 17, 2020, 11:09am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/32 "2020-08-17T11:09:35Z")

</div>

> [@peter.ludemann](#):
>
> If anyone is interested, I can excerpt a simple code example

If you find the time to do it, I would be interested to look at a minimum viable example with comments to explain what does what and where to put our own business code. Thanks for offering !

---

<div class="post-metadata">

**Author:** ![logicmoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/logicmoo/32/193_2.png) [@logicmoo](https://swi-prolog.discourse.group/u/logicmoo)\
**Post date:** [September 30, 2021, 2:02pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/33 "2021-09-30T14:02:46Z")

</div>

Was the problem `wss` and `ws` would have worked?

---

<div class="post-metadata">

**Author:** ![logicmoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/logicmoo/32/193_2.png) [@logicmoo](https://swi-prolog.discourse.group/u/logicmoo)\
**Post date:** [September 30, 2021, 2:08pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/34 "2021-09-30T14:08:10Z")

</div>

Well I just ask _my_ question…

As I understand it, SWI cant yet “serve” secure websockets. (at least not without a webproxy)  
But I am trying to talk to a external server using SWI-Prolog… That external server requires `wss`… Can someone confirm that we can talk to secure websockets just fine?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [September 30, 2021, 2:22pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/35 "2021-09-30T14:22:25Z")

</div>

> [@logicmoo](#):
>
> SWI cant yet “serve” secure websockets

It can. There is nothing special about it. Just do the usual https server and use the same websocket code as you use for http. SWISH does it 🙂

---

<div class="post-metadata">

**Author:** ![logicmoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/logicmoo/32/193_2.png) [@logicmoo](https://swi-prolog.discourse.group/u/logicmoo)\
**Post date:** [September 30, 2021, 2:30pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/36 "2021-09-30T14:30:07Z")

</div>

You meant what we do to serve `wss` from SWISH over Nginx? (Swish serving `http` and `ws`… while Nginx converts to `https` and `wss`?)

Btw, I remember some people having trouble getting apache2 to proxy the WebSocket for SWISH (yet Nginx works fine) … … the other day I got apache2 to work… The trick was moving jus the chat part of SWISH to a subdomain and then proxy only the websocket on its own subdomain ( this only applies to the chat portion of swish… everything else works fine)

Actually what i am up to is I trying to connect SWI-Prolog to `wss://gateway.discord.gg/` … though I think what you saying is set up the ngynx proxy to proxy for `gateway.discord.gg` . I’ll give that try

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [September 30, 2021, 6:53pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/37 "2021-09-30T18:53:32Z")

</div>

> [@logicmoo](#):
>
> You meant what we do to serve `wss` from [SWISH](https://swish.swi-prolog.org/) over Nginx?

Not only. SWISH happily runs using https/wss natively. Yes, the central server uses http/ws and an nginx proxy as that is all the server can support. The server has a central nginx server which proxies requests to LXC containers based on virtual host identifiers.

> [@logicmoo](#):
>
> trying to connect [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) to `wss://gateway.discord.gg/` …

Isn’t that the client side of wss? I suppose that should work too. Not sure I ever used it.

---

<div class="post-metadata">

**Author:** ![logicmoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/logicmoo/32/193_2.png) [@logicmoo](https://swi-prolog.discourse.group/u/logicmoo)\
**Post date:** [October 1, 2021, 7:05am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/38 "2021-10-01T07:05:19Z")

</div>

> [@jan](#):
>
> Not only. [SWISH](https://swish.swi-prolog.org/) happily runs using https/wss natively.

​Aha, good! I was almost sure reading that SWISH has native SSL support but not configured my servers to try it yet. (out of habit​, ​I still run SWISH on a daily basis behind a https/wss proxy)

> [@jan](#):
>
> Isn’t that the client side of wss? I suppose that should work too.

Correct, my use case right now has only to do with the client side. I been trying to troubleshoot why my ​client ​code could understand the socket servers messages just fine but ​yet ​the server is ​not ​understanding my clients ​side’s websocket messages … A few hours into troubleshooting I thought “it be funny if the trouble ​all along was SWI’s secretly ​only ​using `ws://` client (not `wss://` client​)”… So I needed a sanity check that ​ ​`​w​ss`​ was ​work​ing​ and should continue troubleshooting my code.

(ps. I asked about the server because if there was a difference in the time between when SWI’s Non-SSL worked versus when its natively was supporting Server SSL was different . thus indicate a multipart timeline of development for when to expect websockets client and/or server being able to do SSL)

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 1, 2021, 8:08am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/39 "2021-10-01T08:08:26Z")

</div>

Is the problem connecting using wss? I’ve had trouble with that as well in the past. Some servers (and clients) are pretty picky about the headers exchanged during the connect phase. Sometimes they ask more than what is required by the standard. Try to find a working client/server couple, sniff into the communication and compare this with the failing attempt …

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [October 1, 2021, 9:51am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/40 "2021-10-01T09:51:39Z")

</div>

@logicmoo @jan

Should we move the replies related to ws and wss to a new topic?

[Previous page](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722.md?page=1)
