Skip to content

Instantly share code, notes, and snippets.

@jorrizza
Last active December 11, 2015 16:09
Show Gist options
  • Save jorrizza/4626151 to your computer and use it in GitHub Desktop.
Save jorrizza/4626151 to your computer and use it in GitHub Desktop.
Serving stdout using websockets and Go.
package main
import (
"code.google.com/p/go.net/websocket"
"flag"
"log"
"net/http"
"os"
)
var connections map[*websocket.Conn]bool
var stream chan []byte
var registration chan *websocket.Conn
func reader() {
for {
buf := make([]byte, 16)
if _, err := os.Stdin.Read(buf); err != nil {
log.Fatal(err)
}
stream <- buf
}
}
func server() {
for {
select {
case ws := <-registration:
connections[ws] = true
case msg := <-stream:
for ws := range connections {
if _, err := ws.Write(msg); err != nil {
ws.Close()
delete(connections, ws)
}
}
}
}
}
func handleWebSocket(ws *websocket.Conn) {
buf := make([]byte, 1)
registration <- ws
for {
if _, err := ws.Read(buf); err != nil {
break
}
}
}
func handleMain(w http.ResponseWriter, r *http.Request) {
body := "<!DOCTYPE html>\n<html lang='en'>" +
"<head><meta charset=\"utf-8\"><title>stdout</title>" +
"<script>" +
"window.onload = function () {" +
"conn = new WebSocket(\"ws://\"+window.location.host+\"/ws\");" +
"conn.onmessage = function(evt) {" +
"var dump = document.getElementById(\"dump\");" +
"dump.innerHTML = dump.innerHTML + evt.data;" +
"window.scrollTo(0, document.body.scrollHeight);}}" +
"</script>" +
"</head>" +
"<body>" +
"<pre id=\"dump\"></pre>" +
"</body>" +
"</html>"
w.Write([]byte(body))
}
func main() {
connections = make(map[*websocket.Conn]bool)
stream = make(chan []byte)
registration = make(chan *websocket.Conn)
addr := flag.String("p", ":8080", "socket to listen on")
flag.Parse()
http.Handle("/ws", websocket.Handler(handleWebSocket))
http.HandleFunc("/", handleMain)
go server()
go reader()
log.Fatal(http.ListenAndServe(*addr, nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment