Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets.

websocketd

websocketd is a small command-line tool that will wrap an existing command-line interface program, and allow it to be accessed via a WebSocket.

WebSocket-capable applications can now be built very easily. As long as you can write an executable program that reads STDIN and writes to STDOUT, you can build a WebSocket server. Do it in Python, Ruby, Perl, Bash, .NET, C, Go, PHP, Java, Clojure, Scala, Groovy, Expect, Awk, VBScript, Haskell, Lua, R, whatever! No networking libraries necessary.

-@joewalnes

Details

Upon startup, websocketd will start a WebSocket server on a specified port, and listen for connections.

Upon a connection, it will fork the appropriate process, and disconnect the process when the WebSocket connection closes (and vice-versa).

Any message sent from the WebSocket client will be piped to the process's STDIN stream, followed by a \n newline.

Any text printed by the process to STDOUT shall be sent as a WebSocket message whenever a \n newline is encountered.

Download

If you're on a Mac, you can install websocketd using Homebrew. Just run brew install websocketd. For other operating systems, or if you don't want to use Homebrew, check out the link below.

Download for Linux, OS X and Windows

Quickstart

To get started, we'll create a WebSocket endpoint that will accept connections, then send back messages, counting to 10 with 1 second pause between each one, before disconnecting.

To show how simple it is, let's do it in Bash!

count.sh:

#!/bin/bash
for ((COUNT = 1; COUNT <= 10; COUNT++)); do
  echo $COUNT
  sleep 1
done

Before turning it into a WebSocket server, let's test it from the command line. The beauty of websocketd is that servers work equally well in the command line, or in shell scripts, as they do in the server - with no modifications required.

$ chmod +x count.sh
$ ./count.sh
1
2
3
4
5
6
7
8
9
10

Now let's turn it into a WebSocket server:

$ websocketd --port=8080 ./count.sh

Finally, let's create a web-page to test it.

count.html:

<!DOCTYPE html>
<pre id="log"></pre>
<script>
  // helper function: log message to screen
  function log(msg) {
    document.getElementById('log').textContent += msg + '\n';
  }

  // setup websocket with callbacks
  var ws = new WebSocket('ws://localhost:8080/');
  ws.onopen = function() {
    log('CONNECT');
  };
  ws.onclose = function() {
    log('DISCONNECT');
  };
  ws.onmessage = function(event) {
    log('MESSAGE: ' + event.data);
  };
</script>

Open this page in your web-browser. It will even work if you open it directly from disk using a file:// URL.

More Features

  • Very simple install. Just download the single executable for Linux, Mac or Windows and run it. Minimal dependencies, no installers, no package managers, no external libraries. Suitable for development and production servers.
  • Server side scripts can access details about the WebSocket HTTP request (e.g. remote host, query parameters, cookies, path, etc) via standard CGI environment variables.
  • As well as serving websocket daemons it also includes a static file server and classic CGI server for convenience.
  • Command line help available via websocketd --help.
  • Includes WebSocket developer console to make it easy to test your scripts before you've built a JavaScript frontend.
  • Examples in many programming languages are available to help you getting started.

User Manual

More documentation in the user manual

Example Projects

Got more examples? Open a pull request.

My Other Projects

And follow @joewalnes!

Comments
  • Raw protocol support (for binary messages)

    Raw protocol support (for binary messages)

    I propose an option to allow websocketd to be run in "raw mode". In this mode, processes will send/receive message using the WebSocket data framing protocol as defined in RFC6455 (as opposed to newline delimited text). http://tools.ietf.org/html/rfc6455#section-5

    When you'd want this:

    • For text messages that contain "\n"
    • For binary messages
    • For lower level control of ping/pong messages

    Of course this adds complexity to programs as they now need to speak to the data framing protocol, which is more complicated than line delimited text, so programs should only use this when they need it.

    In raw mode, websocketd will continue to act as a socket server, handle HTTP upgrades, perform WebSocket handshakes and route to the correct process. It is only the actual message framing that apps need to worry about.

  • "Could not launch process" when executing windows .cmd files

    i'm trying to use websocketd on windows with the examples provided on this repo and i'm getting an error stating: Could not launch process .\count.cmd (fork/exec .\count.cmd: The directory name is invalid.) Devconsole output: Sun, 22 Feb 2015 13:50:03 +0200 | ACCESS | session | url:'http://127.0.0.1:8080/' id:'1424605803830285500' remote:'127.0.0.1' command:'.\count.cmd' origin:'http://127.0.0.1:8080' | CONNECT Sun, 22 Feb 2015 13:50:03 +0200 | ERROR | process | url:'http://127.0.0.1:8080/' id:'1424605803830285500' remote:'127.0.0.1' command:'.\count.cmd' origin:'http://127.0.0.1:8080' | Could not launch process .\count.cmd (fork/exec .\count.cmd: The directory name is invalid.) Sun, 22 Feb 2015 13:50:03 +0200 | ACCESS | session | url:'http://127.0.0.1:8080/' id:'1424605803830285500' remote:'127.0.0.1' command:'.\count.cmd' origin:'http://127.0.0.1:8080' | DISCONNECT

    i'm running websocketd.exe, as: websocketd.exe --port=8080 --devconsole count.cmd or by: websocketd.exe --port=8080 --devconsole

    Example files are located in the same folder as websocketd.exe and at the web console i'm trying to connect to ws://127.0.0.1:8080/count.cmd and I can also run the .cmd files without problems on command line (running count.cmd gives the desired output).

    when i'm running websocketd using an .exe file as command argument there are no errors and the process starts without problems.

    is there something wrong from my side? are .cmd files still supported as command arguments?

  • SSL connection fails on Windows

    SSL connection fails on Windows

    By running the command: websocketd.exe --port=8080 --ssl --sslcert="localhost.crt" --sslkey="localhost.key" cscript /nologo count.vbs and opening the count.hmtl page at: https://localhost:8080/count.html connection fails with error: TLS handshake error from 127.0.0.1:49246: CryptAcquireContext: Invalid Signature.

    Tested on Windows 7x64 using the count.vbs and count.html provided in examples and websocketd.exe version 0.2.11. Tried both a certificate signed from a CA and a self-signed certificate installed in certmgr.msc.

    The above example worked as expected on Linux with both certificates.

    Any ideas what can be the cause of this issue and how it can be fixed?

  • Setting up Websocketd on RPi

    Setting up Websocketd on RPi

    Wanted to try websocketd on raspberry pi with Raspbian, I started with this page :https://github.com/joewalnes/websocketd/wiki/Raspberry-pi I could complete the first step(Pre-requisites). However, unable to go beyond that. Let me explain. I downloaded go1.2.2.linux-arm-arm-multiarch-armv6-1.tar.gz from Dave's website to a pen drive & tried

    $ cd /media/pendrive $ tar -C /home/pi -xzf go1.2.2.linux-arm-arm-multiarch-armv6-1.tar.gz

    I get the following "tar(child) : go1.2.2.linux-arm-arm-multiarch-armv6-1.tar.gz : cannot open :No such file or directory tar(child) : Error is not recoverable :exiting now tar : child returned status 2 tar: Error is not recoverable :exiting now"

    Then, I wanted to try downloading the file directly to RPi, so tried the following:

    $tar - C /home/pi -xzf http://dave.cheney.net/paste/go1.2.2.linux-arm-arm-multiarch-armv6-1.tar.gz

    which yield the following result: "tar(child) : cannot connect to http:resolve failed gzip :stdin : unexpected end of file tar : child returned status 128 tar: Error is not recoverable:exiting now"

    RPi is connected to internet and it is working.

    Im not sure what is the missing part here. Request advise. Thank you.

    Note : Tried using version 1.2.2 since 1.2 as listed on the page was not available on Dave's website.

  • Regression: large message sizes cause disconnect

    Regression: large message sizes cause disconnect

    I've run into a bug hitting some production systems. I had to roll back to an earlier version of websocketd to fix it.

    It seems that when a very large message is sent, websocketd drops the connection.

    To reproduce, I created a script that produced a very large message followed by a small message.

    #!/bin/bash
    
    # Write out a large number of chars on a single line
    CHARS=80000
    head -c $CHARS < /dev/zero | tr '\0' '\141'; echo
    
    # Acknowledge we're still connected
    echo Success
    

    The WebSocket client will receive the complete first large message successfully, but then the connection will be closed before the second message is received.

    Reducing the CHARS from 80000 to 60000 seems to work fine.

    Attempting to diagnose with strace and wireshark, I can verify that the problem is in the websocketd process. It sends a TCP FIN flag to the websocket client and sends a SIGPIPE to the underlying script. Neither the browser nor the script are expecting the session to be closed at that time.

    I've done some manual testing with git bisect and determined that this regression appeared in 93129e4b, but it's not immediately obvious where the actual problem is.

  • support for connect to backend ip+port ?

    support for connect to backend ip+port ?

    Perhaps this sounds strange. but it would be useful for me at least to have websocketd not fork a program and run it for one connection, but simply connect to a given ip address and port, most likely 127.0.0.1 or a unix socket.

    So for example listening on that port might be an event driven I/O capable process that just wants to talk to new clients via read and write with having to worry about all the web socket stuff, and it might be able to handle 65000 clients, or more with more than one IP address.

    So clients <---> nginx <---> websocketd <---> event driven single thread process ? or clients <---> websocketd <---> event driven single threaded process

    Does this make sense or am I missing something.

  • Websocketd likely needs some resource limits in future

    Websocketd likely needs some resource limits in future

    To prevent forkbombing the server it would be interesting to discuss ability to limit possible amount of connections that server should sustain. After that new connections should be dropped.

    Also, for whom it might matter, might prefer to set timeouts on longest living websockets.

    I don't know websocket golib well to know if some protection is already there.

  • Experimental websocketd binaries (OpenBSD, Solaris)

    Experimental websocketd binaries (OpenBSD, Solaris)

    Blame this: https://twitter.com/joewalnes/status/567497770156957696

    Should be straight forwards go can output openbsd binaries.

    @asergeyev: Update release/Makefile. GOOS settings here https://golang.org/doc/install/source#environment

    @joewalnes: Update website. Modify OpenBSD logo to fit with page.

    @sl4mmy: Hi! Can you help us test?

  • "Rejected Null Origin"

    I get this when running your example application. This is after connecting to it with your sample HTML code. Running Windows 7, Norton 360, Realising that I haven't specified port and it's defaulted to 80. Connect to webpage, says SSL error. 403 forbidden. First tried it with port 8080, same error. This is after trying to access it. Any other details, please do ask for.

    TEMP FIX -

    ./websocketd --port=8080 --staticdir html --loglevel=debug ./count.sh 
    
  • Pretty website for websocketd.com

    Pretty website for websocketd.com

    Would like a nice user friendly website.

    Question: should the primary source of documentation be on the website, or here on the GitHub wiki. Leave a comment if you have an opinion.

  • examples/cgi-bin/dump-env.sh: drop bash dependency

    examples/cgi-bin/dump-env.sh: drop bash dependency

    Replace bashisms with more portable sh idioms. This should both work out of the box on more systems, and also fixes the example on systems like OpenBSD where the official system bash package installs the executable in a location other than /bin.

    Original patch from Dmitrij D. Czarkoff [email protected] with tweaks from me.

    Signed-off-by: Kent R. Spillner [email protected]

  • Allow listening on a Unix Domain Socket

    Allow listening on a Unix Domain Socket

    I use this in conjunction with local SSH port forwarding. The benefit is that I can run a server on a remote machine without allowing other users with login access to reach it. The service becomes available on the SSH client on an IP port but on the SSH server only via a private socket.

  • MIPS compilation?!?

    MIPS compilation?!?

    This is not really an issue but has anyone had success compiling for MIPS. I took the source code and did the following:

    export GOARCH=mips
    export GOMIPS=softfloat
    export GOOS=linux
    export CC=/compile/mips-gcc472-glibc216-32bit-r2.3.3/bin/mips-linux-gnu-gcc
    ##  (Also tried with mips-linux-uclibc-gnu-gcc since the device has uclibc)
    make clean
    make
    

    It creates a websocketd binary but when I run it on the device I get:

    ./websocketd: line 1: syntax error: unexpected "("

    When I run the 'file' command on it, I get:

    websocketd: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), statically linked, stripped

    When I run the 'file' command on another working binary file on the system, I get:

    hl_client: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped

    Thanks for any help...

  • fix(sec): upgrade github.com/gorilla/websocket to 1.4.1

    fix(sec): upgrade github.com/gorilla/websocket to 1.4.1

    What happened?

    There are 1 security vulnerabilities found in github.com/gorilla/websocket v1.4.0

    What did I do?

    Upgrade github.com/gorilla/websocket from v1.4.0 to 1.4.1 for vulnerability fix

    What did you expect to happen?

    Ideally, no insecure libs should be used.

    The specification of the pull request

    PR Specification from OSCS

  • New option for binary websockets

    New option for binary websockets

    Instead of specify the parameter --binary=true it would be great to have a parameter --bindir=some_path where websocketd serves binary connections. In this manner you could use the same instance to serve text and binary ws connections depending on the script location.

  • Pipe multiple CLI apps to generate a website

    Pipe multiple CLI apps to generate a website

    Problem Description:

    I am working on a solution to pipe multiple CLI apps to generate a website.

    In Linux terms, it will look like:

    Request | CLI_APP --output json | ADD_UI --output web | ADD_HTTP_RESPONSE_MESSAGE > Response
    

    I am using --output json with CLI_APP to say that the CLI_APP will output json (for REST API).

    Here, --output web with ADD_UI will add HTML, CSS, JS etc. to the JSON output.

    I am using ADD_HTTP_RESPONSE_MESSAGE to add HEADERS, response code etc. This is because, I want the CLI apps to be totally independent. I do not want to add HTTP response message to CLI_APP or ADD_UI output so that I can reuse these tools in case I decide to make a GUI app or mobile app or something later where HTTP is not involved.

    Question:

    I think websocketd is the solution of my problem. am I right? Or am i missing something?

    In your example codes you did not print any HTTP header or status code, so I assume you deal with the http stuff, and we just print to stdout. I mean, I will not need ADD_HTTP_RESPONSE_MESSAGE. Will it be a correct statement?

    In your examples, I did not find how to deal with GET or POST requests. In CGI, we use QUERY_STRING to get data from GET request and then parse it. For, POST, the data is sent as input stream to the program. since the server passes information to this program as an input stream, it sets the environment variable CONTENT_LENGTH to the size of the data in number of bytes (or characters). We can use this to read exactly that much data from standard input. How to deal with GET and POST request in websocketd.

    In the count example, there is count.html. It calls ./count.sh via var ws = new WebSocket('ws://localhost:8080/');. So, first we are getting the HTML file, it is calling the sh file. But I want to first hit ./count.sh and it will generate the count.html file. Is it possible?

    How to pipe multiple commands to get the output. For example, how can I get the output of ps -ef | grep root | wc -l using websocketd?

Encrypted-websocket-chat - Encrypted websocket chat using golang

Encrypted websocket chat First version written in python This version should be

Sep 15, 2022
Websocket-chat - A simple websocket chat application
Websocket-chat - A simple websocket chat application

WebSocket Chat App This is a simple chat app based on websockets. It allows user

Jan 25, 2022
Go client for an OBS WebSockets server

goobs It's a Go client for Palakis/obs-websocket, allowing us to interact with OBS Studio via Go. disclaimer This project is still a work-in-progress.

Jan 1, 2023
A simple server to convert ATK-IMU901 serial data into websocket stream

A simple server to convert ATK-IMU901 serial data into WebSocket stream.

Jan 31, 2022
a simple shitty project for learn more about websockets

video-transmission A simple shitty project for learn more about websockets. For run this you only need to have docker in your computer and then execut

Mar 29, 2022
handling 1M websockets connections in Go

Going Infinite, handling 1M websockets connections in Go This repository holds the complete implementation of the examples seen in Gophercon Israel ta

Jan 1, 2023
Kucoin proxy for freqtrade that is using websockets to maintain candlestick/klines data in memory

Kucoin proxy for freqtrade that is using websockets to maintain candlestick/klines data in memory, thus having great performance and reducing the amount of API calls to the Kucoin API. All other calls are proxied as usual.

Dec 5, 2022
A small and basic service to echo requests made via websockets

Ping Service A small and basic service to echo requests made via websockets, can be useful for measuring latency between clients and this service. Run

Nov 18, 2021
Websockets - Chaotic Web Sockets With Golang

Chaotic Web Sockets The intention of this project is to show the behavior of a s

Jan 21, 2022
BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication.

BrisGolang BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication. Usage You can play

Nov 1, 2021
Just a PubSub Websocket Server

Eventual Agent Just a PubSub Websocket Server The eventual agent allows cluster local apps to subscribe and publish over network. Goals Provide a WebS

Dec 24, 2022
HLive is a server-side WebSocket based dynamic template-less view layer for Go.
HLive is a server-side WebSocket based dynamic template-less view layer for Go.

HLive HLive is a server-side WebSocket based dynamic template-less view layer for Go. HLive is a fantastic tool for creating complex and dynamic brows

Jan 8, 2023
Websocket server, implemented flow Room style

ignite A websocket server module. Require redis to scale to multi nodes. Client/server message follow format type Message struct { Event string

Apr 10, 2022
API that upgrades connection to use websocket. Contains server and client and testing how they communicate

Websocket Test API How to execute First run server using: make run-server. Then run many client instances with: make run-client. Then start typing in

Dec 25, 2021
Websocket server. Get data from provider API, clean data and send to websoket, when it's changed.

Описание Сервис получает данные по киберспортивным матчам CS:GO от провайдера, структурирует, очищает от лишнего и отправляет всем активным вебсокет к

Apr 6, 2022
A fast, well-tested and widely used WebSocket implementation for Go.

Gorilla WebSocket Gorilla WebSocket is a Go implementation of the WebSocket protocol. Documentation API Reference Chat example Command example Client

Jan 2, 2023
WebSocket Command Line Client written in Go

ws-cli WebSocket Command Line Client written in Go Installation go get github.com/kseo/ws-cli Usage $ ws-cli -url ws://echo.websocket.org connected (

Nov 12, 2021
proxy your traffic through CDN using websocket

go-cdn2proxy proxy your traffic through CDN using websocket what does it do example server client thanks what does it do you can use this as a library

Dec 7, 2022
Chat bots (& more) for Zoom by figuring out their websocket protocol
Chat bots (& more) for Zoom by figuring out their websocket protocol

zoomer - Bot library for Zoom meetings Good bot support is part of what makes Discord so nice to use. Unfortunately, the official Zoom API is basicall

Dec 14, 2022