websocketd icon indicating copy to clipboard operation
websocketd copied to clipboard

Improve 10-minute example by adding reading from STDIN

Open ctshh opened this issue 9 years ago • 17 comments

The 10 minute example does a good job on explaining how to display STDOUT, yet fails to (somehow interactively?) read STDIN input from the user back to the running script. I'd appreciate an example (or an amended 10-minute example) on how to do this.

I'd appreciate being shown how to bring the classic display-read-compute-display shellscripts to the browser:

#!/bin/bash
echo "Some initial text."
echo "Now enter your input text: "
read sometext
echo "You entered --${sometext}--."
(...)

This works quite well using the developer console, as it has an "input" field visible all the time (which can be used once an input is required). But how to bring such an input field to the example html stays unclear.

ctshh avatar Mar 04 '15 08:03 ctshh

Here is small migration from count.html to greeter.html that would work with greeter examples:

https://gist.github.com/asergeyev/a33f0f595ff551a5b8d3

Your multi-line output is tiny bit different, it might require appending to some HTML element instead of resetting it.

asergeyev avatar Mar 04 '15 13:03 asergeyev

I think it would be clearer if we created a tutorial dedicated to reading stdin.

I'd also like to add a tutorial on how to build a chatroom (which implies sharing state between programs).

Leaving this issue open as a reminder to do it.

joewalnes avatar Mar 04 '15 16:03 joewalnes

I'd also like to add a tutorial on how to build a chatroom (which implies sharing state between programs).

I'd say this is part of the underlying script.

ctshh avatar Mar 05 '15 06:03 ctshh

Is the addition of tutorials and examples going to hold up releases ?

I think unit tests should precede examples and tutorials.

On 5 March 2015 5:33:19 pm AEDT, ctshh [email protected] wrote:

I'd also like to add a tutorial on how to build a chatroom (which implies sharing state between programs).

I'd say this is part of the underlying script.


Reply to this email directly or view it on GitHub: https://github.com/joewalnes/websocketd/issues/135#issuecomment-77314326

Sent from my Android device with K-9 Mail. Please excuse my brevity.

aj664 avatar Mar 05 '15 07:03 aj664

Agreed as long as the documentation is written by the same people that do the code. If you'd outsource documentation to someone else though.... ;)

ctshh avatar Mar 05 '15 10:03 ctshh

Re releases: Documention (including tutorials, website, examples) and the underlying code itself is constantly improving and being released incrementally. Sometimes it makes sense to release them in lock step, but most of the time they'll just be released when ready assuming there's no negative side effect.

Re unit tests: These are internal implementation details. It's not an API, it's an end user tool and most users don't even know what language it's built in (nor should they). So I don't see unit tests as a valuable addition to the end user learning process - in fact they're more of a distraction. Please don't read that as me being against unit tests - I am absolutely for them, just not in the context of this documentation discussion.

Re who writes the docs: That's me.

joewalnes avatar Mar 05 '15 12:03 joewalnes

Before having found this thread I wondered why the recommended syntax is not

 my-program | websocketd --port=8080

as long as the program does not expect to read from stdin, such syntax makes more sense to me and it avoids --passenv.

nichtich avatar Mar 28 '15 21:03 nichtich

ha :) @joewalnes if we would allow this kind of syntax it could solve demuxing problem once and for all.

But that causes need for flag that would be incompatible with cmd... making it into something like

$ vmstat 1 -n | websocketd --port=8080 --pipe

asergeyev avatar Mar 29 '15 03:03 asergeyev

This is a wildly different case. Non interactive, output only, broadcast.

Does it buffer responses (eg store data so when clients connect it gets replayed?).

It's so different I would make it another tool. It's a very useful tool, I just wouldn't have it in websocketd. Too confusing. Also WebSockets are overkill - I would use EventSource instead: https://medium.com/@joewalnes/tail-f-to-the-web-browser-b933d9056cc

joewalnes avatar Mar 29 '15 12:03 joewalnes

I came from exactely this article in which you recommend to use websocketd. You are right about the question of buffering for multiple clients - one would have to define a buffer length in number of lines so every new client gets send the buffer first after receiving following lines as broadcast to all connections. If buffering is not needed, we could open and write to a named pipe and let websocketd read from this pipe:

$ mkfifo my_pipe
$ vmstat 1 -n > my_pipe &
$ websocketd --port 8080 cat my_pipe

Unfortunately this hack requires to manually set up the pipe and do cleanup afterwards, why not let websocketd do it?

nichtich avatar Mar 30 '15 08:03 nichtich

we're way off topic here but, Nope your suggestion with mkfifo would not work since each new cat would steal data from previous one, you could not make them concurrent.

asergeyev avatar Mar 30 '15 20:03 asergeyev

Ooops hit wrong button!

joewalnes avatar Mar 31 '15 12:03 joewalnes

Indeed, we are off topic.

@nichtich If you want to continue this discussion about different ways of streaming to multiple clients, please can you start a new issue for discussion. This issue is about something entirely different.

I also recommend reading #95, #50, and #132 to get some context about broadcast from similar discussions.

Leaving this issue open as the original documentation related issue is still todo.

joewalnes avatar Mar 31 '15 15:03 joewalnes

I just created an example that demonstrates two way communication using c++: https://github.com/joewalnes/websocketd/wiki/CPP-Input-Output-Example

mbbackus avatar Jan 03 '16 02:01 mbbackus

@mbbackus I think your example needs to be changed to react to end of input stream. It also should be fixed for errors (see further below).

When web-client disconnects, websocketd closes stdin of the running command. When command is still running couple seconds later (which means resources are used for something that does not do any work), websocketd would start using signals to terminate it. That outcome is somewhat "error handling" rather than normal.

Also any command that websocketd is supervising should be possible to use on it's own, say with test stream of input data. Your command would not ever finish, try "echo 1234 | ./example", it should acknowledge message arrival once and finish. Currently there is some problem that causes code continuously say that same message arrived again and again.

Also at least my default compiler was not able to build your code until I added unistd.h for usleep to work. Which IMO is part of another problem, you try to use global variable to pass message between threads with futex but only reading from that variable once a second. This means that thousands of messages could be skipped for a client that's fast enough to send data to client. Something like "seq 1 10 | ./example" should also work and handle 10 distinct input messages.

asergeyev avatar Jan 04 '16 13:01 asergeyev

The code you see here is a basic example of two way communication. I compiled and tested it before posting it. It's similar to what's on my robot. Sorry it's not working for you. Feel free to change it as you see fit. I was just so grateful to the guys that made this available that I thought I'd pay them back by helping out a little with the documentation.

mbbackus avatar Jan 04 '16 15:01 mbbackus

I just wonder if you can finish it. For example make sure it might work with passing messages faster than every second.

BTW if your program also not reacting to stream closing and you run it with websocketd and --loglevel=debug you might see that KILL signals are getting issued, which is really quite an overhead on everything.

asergeyev avatar Jan 08 '16 20:01 asergeyev