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

Overview

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!

Issues
  • SSL support

    SSL support

    Support https and wss.

    feature 
    opened by joewalnes 38
  • 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.

    discussion 
    opened by joewalnes 31
  • "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?

    defect 
    opened by eparon 25
  • 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?

    opened by Konstantinacc 21
  • 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.

    opened by Shrest 21
  • 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.

    defect 
    opened by joewalnes 21
  • Is there a more convenient way to install this package?

    Is there a more convenient way to install this package?

    Such as brew on OS X? It's annoying to directly download the executable instead of using a package manager.

    feature 
    opened by fanchangyong 20
  • 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.

    opened by jbardu 20
  • 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.

    opened by asergeyev 18
  • "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 
    
    opened by popey456963 16
  • Feature Request: Add --sslca= to command line options.

    Feature Request: Add --sslca= to command line options.

    During the discussion for SSL in 2014, this (the command-line option) was requested as an option. While the other options have been implemented, I would like to request the additional command-line option "--sslca=".

    I tried the option in version 0.4.1 but it was not implemented; unless I am missing something.

    Use case: A public webserver, with a signed certificate from an an approved CA, limits websocket access to known, self-signed, client certificates. Developers create their own key-pairs and supply the public certificate to IT for websocket access.

    Problem: Currently, the software requires client certificates signed by an approved certificate authority since the CA list used is system wide. Therefore the websocket server refuses connections from self-signed certificates. with the following error: TLS handshake error from ********:****: remote error: tls: unknown certificate authority To gain the function, modification of the system-wide certificate store to add the clients' certificate is required. The system-wide certificate store is automatically updated regularly (e.g. by Lets Encrypt or IT), overwriting the changes, and modification of the vanilla CA file is inherently a security risk, changing it's verifiable hash.

    Resolution: Use a specific CA file only listing allowed clients' public certificates, obviating the need to modify system-wide CA files. This would allow the clients to verify the public server against the sites public certificate (by an approved CA) while accepting known clients identified by their self-signed certificate. I believe this would require a command-line or file configuration setting to define the certificate store to use. (e.g. --sslca=).

    Nice-to-haves: The ability to define a directory of certificates rather than a single file for --sslca=.

    opened by Splediferous 0
  • Can you make websocketd execute the program before any client connecting

    Can you make websocketd execute the program before any client connecting

    First of all, thank you for building this ;)

    I have a program i would like to be running before any clients connect to the websocket. Is that possible?

    ../websocketd --port=8080 --address=$(hostname -I) sudo someprogram

    opened by argmhz 2
  • help make it work

    help make it work

    Hi! Sorry for opening an issue to ask this but I can't figure out how to make it work. My goal is to run a .bat file on the server side, I've placed websocked.exe on c:/ I've created a bat to launch it with proper paramenters websocketd --address 192.168.24.2 --port 6000 --dir=c:
    I've created next a simple bat file to execute. Websocket is running and port 6000 is opened, now I've created an html file containing:

    <!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://192.168.24.2:6000/');
      ws.onopen = function() {
        log('CONNECT');
      };
      ws.onclose = function() {
        log('DISCONNECT');
      };
      ws.onmessage = function(event) {
        log('MESSAGE: ' + event.data);
      };
    </script>
    

    I've specified the IP of server, same address with I executed websocketd. I put the file in the http server folder, I open the file with browser, it wrote disconnected, nothing is sent on port 6000. From your code I don't understand how it works, there is no call to the script, just <pre id="log"></pre> which I don't know what it means. No external libraries are invoked so you suppose the browser already knows what it should do. I don't see where to specify the command to execute (the bat file). Thank you a lot to clarify me

    opened by Barabba11 1
  • proxy?

    proxy?

    I don't know how to pose this question...

    but can websocked instead of listening on a local port, connect to a remote server?

    Let's say machine A is behind a firewall. Machine B is rechable by the world Machine C wants To connect to machine A

    il would be nice if websocked could connect to a server on machine B so machine C can connect to the same server and talk to machine A

    opened by Zibri 1
  • ModuleNotFoundError under Python3's venv (virtual environment)

    ModuleNotFoundError under Python3's venv (virtual environment)

    version 0.4.1 platform Windows amd64

    My Python3 program need to run under venv to access some modules only installed to the venv. After I entered the venv, I can run the program: main.py, then under the same venv, I attempted to run the websocketd:

    websocketd --port=8080 py main.py

    It spit out an error: "ModuleNotFoundError: No module named" and disconnected/terminated.

    I wonder if there is some special settings / parameters I need to apply in order to run the Python program under venv. Or Python venv cannot be supported?

    opened by bertlea 3
  • Open a discussion board?

    Open a discussion board?

    Many issues on this repo are really just questions that are not actually issues with Websocketd. It may be time to open a discussion board. As I understand this is a relatively new thing for GitHub repos.

    When I see questions regarding PHP or C in websocketd I usually check it out. In PHP websocketd is the best way to use ws in windows systems as forking is currently not available in PHP-WIN OS. While I don't use it on my prod anymore, since I wrote the ws protocol in php for more usability regarding OS level ops. I use websocketd as a flaggable option still and will continue to do so with support to my users. I've added a bit of Doc here in the Wiki as well for PHP and C. While learning in college I found this to be an amazing stepping stone for my personal development.

    I hope to continue helping the community as long as this repo remains active.

    Thanks for everything :)

    opened by RichardTMiles 1
  • Feature Request: STDERR redirected through websockets

    Feature Request: STDERR redirected through websockets

    It seems this program swallows stderr output,

    ./websocketd --loglevel=debug --port 8080 --devconsole -- perl -E'$|++; say for 1,2,3,4; warn $_ for 7,7,7; die 42;'
    

    Yet when I check out ws://localhost:8080 I don't see the messages for 7,7,7 or 42 anywhere...

    open
    ws://x1c7:8080/ 
    onopen
     
    onmessage
    1 
    onmessage
    2 
    onmessage
    3 
    onmessage
    4 
    onclose
    [Clean: false, Code: 1006, Reason: none] 
    send »
    

    Is there a way to tell websocketd to wrap the stream in JSON and tell us what stream it is, or something of the like?

    opened by EvanCarroll 6
  • Execution wrapper / controller for websocketd

    Execution wrapper / controller for websocketd

    Hi. Thanks you for your work on this project

    I have been working on a side project I use as some sort of controller to run programs through websocketd

    It is a single static binary which lets you define what need to be run through json files (which can be statically or dynamically generated through an api). A connection to websocketd on ws://127.0.0.1:8080/myscript will lookup json file myscript.json which describes what needs to be run

    Example

    {
        "cmdLine":"traceroute -n 8.8.8.8",
        "forwardStderr":true,
        "timeout":10
    }
    

    I thought it might be useful to someone else ;)

    Feel free to close issue if inapropriate

    opened by ctn-malone 0
  • Request: Configuration file

    Request: Configuration file

    I've been using Websocketd for some time now and its a really useful tool. However, when there are multiple instances of websocketd on a development server, utilized by multiple people for various purposes, it becomes a real nuisance to take care of the machine in the event of an accident when there are multiple processes using 10+ parameters in their command line, expanding over 3+ lines in a process list.

    Generally I believe it would be quite easier for websocketd users as well if the settings were defined in a standalone config file, rather than passed as arguments. If this was C, Python, PHP, or Bash I would've spent the couple of hours needed to expand the functionality of config.go and filed a PR, but given that websocketd is based on Go, at which I am not fluent, I'd prefer to leave that to the professionals - you guys.

    I hope you understand my point and you will agree with me that passing settings as 10+ script parameters is easier and quicker to do for a prototype, but for the long run - its just unprofessional. A config file is the better approach and I do believe that you have reached the point to integrate this given the age of websocketd.

    opened by xPh03n1x 5
  • subscription in http://websocketd.com/ does not work

    subscription in http://websocketd.com/ does not work

    I've just tried to subscribe for "Announcements, new features, security advisories" in http://websocketd.com/ but I get a "404: Page not Found" from mailchimp

    opened by francescor 2
Releases(v0.4.1)
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 WebSoc

Joe Walnes 15.7k Sep 14, 2021
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

Gorilla Web Toolkit 15.5k Sep 17, 2021
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.

Andrey Kaipov 24 Sep 12, 2021
Simple example for using Turbos Streams in Go with the Gorilla WebSocket toolkit.

Go Example for TurboStreams over WebSockets Simple example for using Turbos Streams in Go with the Gorilla WebSocket toolkit.

Jan Stamer 16 Jun 29, 2021
:notes: Minimalist websocket framework for Go

melody ?? Minimalist websocket framework for Go. Melody is websocket framework based on github.com/gorilla/websocket that abstracts away the tedious p

Ola 2.2k Sep 20, 2021
websocket消息推送服务

balloons-websocket 用于构建实时应用程序的基础架构和API,balloons提供了最好的基础架构和API,以大规模地提供实时体验。向最终用户提供快速稳定的实时消息。让我们处理实时消息传递的复杂性,以便您可以专注于代码。 balloons的实时API向开发人员公开了整个balloon

null 11 Apr 4, 2021
Tiny WebSocket library for Go.

RFC6455 WebSocket implementation in Go.

Sergey Kamardin 4.1k Sep 22, 2021
gatews - Gate.io WebSocket SDK

gatews - Gate.io WebSocket SDK gatews provides new Gate.io WebSocket V4 implementations. It is intended to work along with gateapi-* series to provide

gate.io 19 Aug 29, 2021
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

Christopher Tarry 41 Sep 2, 2021
A modern, fast and scalable websocket framework with elegant API written in Go

About neffos Neffos is a cross-platform real-time framework with expressive, elegant API written in Go. Neffos takes the pain out of development by ea

Gerasimos (Makis) Maropoulos 367 Sep 16, 2021
run shell scripts by websocket with go lauguage

go_shell_socket run shell scripts by websocket with go lauguage Usage pull project get gin and websocket with go get config config.json file build it

soQ 18 Jun 3, 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

jm33-ng 31 Sep 9, 2021
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

ranon rat 5 Jul 14, 2021
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 (

Kwang Yul Seo 16 Jun 13, 2021
Terminal on browser via websocket

Terminal on browser via websocket. Supportted OS Linux Mac

skanehira 122 Aug 27, 2021
simpleChatInGo - This is a simple chat that i made for fun asnd learn more about websocket

simpleChatInGo This is a simple chat that i made for fun asnd learn more about websocket deploy For deploy this you only need to run the command : $ d

ranon rat 6 Aug 7, 2021
go-socket.io is library an implementation of Socket.IO in Golang

go-socket.io is library an implementation of Socket.IO in Golang, which is a realtime application framework.

Googol Lee 4.3k Sep 24, 2021