Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ten minute tutorial - confusing #438

Open
MdeLv opened this issue Mar 2, 2023 · 7 comments
Open

Ten minute tutorial - confusing #438

MdeLv opened this issue Mar 2, 2023 · 7 comments

Comments

@MdeLv
Copy link

MdeLv commented Mar 2, 2023

Hi,

I gave a try to the 10 mn tutorial.
I have a basic knowledge of web sockets.
I couldn't get the last section of this small tutorial working (count.html).

Here are questions and suggestions to improve this tutorial.

A simple endpoint
Ok, the script count.sh works (CLI).

Starting the WebSocket server"
$ websocketd --port=8080 --staticdir=. ./count.sh
Ok. Launched. But no interaction is possible.

It is said

--staticdir=. Allow websocketd to serve count.html as a static file
However there is no count.html yet... This is confusing.
I suggest:
--staticdir=. Allow websocketd to serve any .html file that is in the script directory as a static file

I suggest a warning such as

No interaction is possible with the server from the browser although the server indicates the following :
Starting WebSocket server : ws://HOSTNAME:8080/
Serving CGI or static files : http://HOSTNAME:8080/

Testing with the dev console
It lacks a clear sequence from previous step:
1/ stop the server (ctrl c)
2/ start the server with the --devconsole option instead of the --staticdir option (they are NOT compatible).
$ websocketd --port=8080 --devconsole ./count.sh

It is said "Point your browser to http://localhost:8080/" while the server displays "Developer console enabled : http://HOSTNAME:8080/". This is misleading.
I suggest to clarify "Point your browser to http://localhost:8080/ and NOT to http://HOSTNAME:8080/ as shown in the server side (CLI).".
Why is http://HOSTNAME:8080/ not working? What do you think about explaining it? (Maybe because of "Connection not secure").

Building a web-page that connects to the WebSocket
It lacks a clear sequence from previous step:
1/ stop the server (ctrl c)
2/ start the server with the --staticdir option:
$ websocketd --port=8080 --staticdir=. ./count.sh
etc.
Open this page:
http://localhost:8080/count.html

"It may not work if you open it directly from disk using a file:// URL because of a null origin (WebSockets cross site security policy). (NOTE the URL in the image is wrong:)"

Of course file:///path/to/tmp/count.html is not working.

? So what is the URL to use?
http://localhost:8080/count.html ?...

It does not work.
I feel that the browser may have an unstable behavior. Do you have recommendation? (checks...)

I could not get the count.html working. Can you help for that?
Thanks.

@MdeLv
Copy link
Author

MdeLv commented Mar 9, 2023

I would appreciate even a short feedback.
Thanks.

@matvore
Copy link

matvore commented Mar 9, 2023

I think the owner of this repo is not interested in it anymore. I haven't seen any activity from joewalnes for a few months. I doubt any of the forks are interested in maintaining a wiki.

I have a fork at http://github.com/matvore/websocketd - I have made modest additions and quietly merged PRs from this repo (like serve on UDS port). I would welcome PRs including new docs (not sure about starting a wiki)

--staticdir=. Allow websocketd to serve count.html as a static file

However there is no count.html yet... This is confusing.

Agreed. Any mention of count.html and --staticdir=. should come after the demo of running with the devconsole. And the command lines to a) start in devconsole mode and b) in --staticdir=. mode should be shown fully only when they are needed to follow the tutorial.

I suggest:
--staticdir=. Allow websocketd to serve any .html file that is in the script directory as a static file

It's unclear what "script directory" is, and it can serve any file, not just .html. . simply should be interpreted as $PWD (the directory you are in when you start the script)

Why is http://hostname:8080/ not working? What do you think about explaining
it? (Maybe because of "Connection not secure").

I assume it is because almost no home network is set up to resolve locally-configured hostnames correctly.

It does not work.
I feel that the browser may have an unstable behavior. Do you have
recommendation? (checks...)

I tried the tutorial successfully, using http://localhost:8080/ and not file:///.... It is basically correct even though it has issues.

What happens when you navigate your browser to it? Does it make you wait a long time and timeout? Does it show some resolution or error like 404, or an empty white page? Consider opening the browser's Javascript console (e.g. Ctrl+Shift+J in Chrome) and checking log output.

@matvore
Copy link

matvore commented Mar 9, 2023

Above, when I said "the directory you are in when you start the script" I meant "the directory your shell is in when you start websocketd".

@MdeLv
Copy link
Author

MdeLv commented Mar 9, 2023

1/ Although I made no change, now http://localhost:8080/ and http://HOSTNAME:8080/ are both UP (HOSTNAME always defined and resolved on this host).

2/ I changed the suggestion in:

--staticdir=SOME_PATH : allows websocketd to serve as a static file any file that is in the targeted directory targeted with the option --staticdir=SOME_PATH
Is it OK for you?

3/ Regarding the css rendering trouble, I only can get this:
image

Delving into the FF console/CSS, I could see a CORS error:

Error processing sheet 
CSSStyleSheet 
 DOMException: CSSStyleSheet.cssRules getter: Not allowed to access cross-origin stylesheet

I tried with internal css (the example count.html), with external css and inline css: l got the same css error.

I tried to set on FF, in about:config: network.cors_preflight.allow_client_cert: true or content.cors.disable but I got the same result.
I tried with Chrome: no CORS error. But no css rendered.

I finally could stop the CORS error message with FF with "Disable restrictions for this tab" on NoScript extension (because "Set all on this page to temporarily TRUSTED" was not enough...).
But I got the same result : no rendering of the css (which is quite large: font: bold 150px arial).
...

In fact, although I mentionned http://localhost:8080/ in this issue, I was using http://localhost:8081/.
I finally tried to stop a test server that was running on that port 8080 and did the 10 mn tutorial on port 8080: it worked (?!):

image

For a reason that still needs to be found, when I entered http://localhost:8080/count.html the Console displayed a request on port 8080!! Firefox can’t establish a connection to the server at ws://localhost:8080/.

At last, with this hint, I remembered that it's also necessary and enough to modify the embedded script with port 8081 to use that port... hum...
var ws = new WebSocket('ws://localhost:8081/');

In production, I would have one place for defining the port, say variable PORT, before modifying the script with a sed command (or heredoc-generating the script with the defined port) and use the parameterized command websocketd --port=${PORT} ....

Now, all is fine with this 10 mn tutorial.
Thanks for your stimulating message.

@MdeLv
Copy link
Author

MdeLv commented Mar 9, 2023

I'm mainly used to client-server web applications and was exploring websockets in order to provide a web GUI to some programs. I also heard that it's faster than client-server web apps. I don't know how much faster, but I read something about 2 orders of magnitude : 100-500 (full-duplex Vs half-duplex).

I found http://websocketd.com/ but was not aware of all the unix websockets solutions.

You are mentioning your fork at http://github.com/matvore/websocketd and additions.
Can you tell what is the situation of websocketd compared to other implementations?
What is the architecture?
How do you use it?
Is it a "toy" implementation or is it possible to use it in a production (even limited) context? I mean "What are the risks?".
Also, compared to http client/server, can you tell for which use cases websocketd is nice to use?
Thanks.

@matvore
Copy link

matvore commented Mar 10, 2023

--staticdir=SOME_PATH : allows websocketd to serve as a static file any file that is in the targeted directory targeted with the option --staticdir=SOME_PATH

Is it OK for you?

I cloned the wiki at https://github.com/matvore/websocketd/wiki/ and used a more brief wording. I did not make any other changes we discussed. I invited you as a collaborator. Feel free to improve upon the tutorial in any way.

About the CORS error, I tried the tutorial with Firefox and didn't have an issue. I guess this is because of the NoScript extension, which I'm not familiar with.

In production, I would have one place for defining the port, say variable PORT, before modifying the script with a sed command
(or heredoc-generating the script with the defined port) and use the parameterized command websocketd --port=${PORT} ....

In my server, I use 'ws://' + location.host + '/{etc...}' in Javascript to formulate the ws address. Probably good enough for simple use cases, but your approach would be required if your server config is more complicated, like with separate ports for ws and https.

Now, all is fine with this 10 mn tutorial.
Thanks for your stimulating message.

Happy to help out.

Can you tell what is the situation of websocketd compared to other implementations?
What is the architecture?
How do you use it?

I haven't looked much at the part of the code that I didn't need to change. I did take a look at an alternative known as lighttpd, which is C based and very mature, though may be more tricky to configure. I trust C dependencies more than any other language, as they tend to be very focused in purpose and easy to hack on.

Lighttpd supports websockets with FastCGI, which means you don't need a separate server process for each websocket stream. The problem is I didn't know about lighttpd until I had already written my tool using websocketd's design, which is separate process per stream.

If you are going to support a massive QPS figure then websocketd may not be the best choice.

For my use case I can deal with an extra process per stream. I use it for a terminal emulator based on hterm. Each tab is a separate terminal. That means I can use Ctrl+Shift+A to search open tabs including shell sessions. This integrates better with the ChromeOS window manager than using tmux and the default ssh app for ChromeOS (disclaimer - I am on Google's ChromeOS team).

My terminal emulator toy already needs to start the shell, a few supporting processes, and a Chrome tab for each terminal window anyway.

Another issue with websocketd is that Websocket responses are separated with a newline, and I have had encoding issues for non-ascii text that I never nailed down - could have been my fault. Anything with a newline (and maybe non-ascii text) will need to be escaped. I did not have trouble with non-printable ascii characters (including those less than 0x20)

@gstrauss
Copy link

gstrauss commented Mar 11, 2023

I did take a look at an alternative known as lighttpd, which is C based and very mature, though may be more tricky to configure.

lighttpd supports Upgrade: websocket with mod_cgi cgi.upgrade = "enable" or mod_proxy proxy.header = ("upgrade" => "enable"). If your FastCGI handles Upgrade: websocket by sending an intermediate response, then your FastCGI can handle websockets, too.

lighttpd mod_wstunnel can terminate a websocket connection to client and pass the data payload to a backend which does not need to know anything about websockets. This is useful if the client and backend are encapsulating a different protocol (e.g. json messages) over websockets (between client and web server). This can be used for simple network daemons listening on a unix domain socket, accepting and serving connections, and scales quite well.

websocketd (not lighttpd) allows for websockets with even simpler command-line processes using stdin and stdout, and without the command-line process having to handle even basic networking, though at the cost of a separate process per stream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants