diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/gorilla/websocket/examples')
8 files changed, 509 insertions, 5 deletions
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md index 08fc3e65c..5df3cf1a3 100644 --- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md @@ -17,3 +17,4 @@ using the following commands. $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat` $ go run *.go +To use the chat example, open http://localhost:8080/ in your browser. diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go index 7cc0496c3..22816f09f 100644 --- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go @@ -88,12 +88,8 @@ func (c *connection) writePump() { } } -// serverWs handles websocket requests from the peer. +// serveWs handles websocket requests from the peer. func serveWs(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - http.Error(w, "Method not allowed", 405) - return - } ws, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(err) diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md new file mode 100644 index 000000000..c30d3979a --- /dev/null +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/README.md @@ -0,0 +1,19 @@ +# Command example + +This example connects a websocket connection to stdin and stdout of a command. +Received messages are written to stdin followed by a `\n`. Each line read from +from standard out is sent as a message to the client. + + $ go get github.com/gorilla/websocket + $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/command` + $ go run main.go <command and arguments to run> + # Open http://localhost:8080/ . + +Try the following commands. + + # Echo sent messages to the output area. + $ go run main.go cat + + # Run a shell.Try sending "ls" and "cat main.go". + $ go run main.go sh + diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html new file mode 100644 index 000000000..72fd02b2a --- /dev/null +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/home.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<title>Command Example</title> +<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> +<script type="text/javascript"> + $(function() { + + var conn; + var msg = $("#msg"); + var log = $("#log"); + + function appendLog(msg) { + var d = log[0] + var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight; + msg.appendTo(log) + if (doScroll) { + d.scrollTop = d.scrollHeight - d.clientHeight; + } + } + + $("#form").submit(function() { + if (!conn) { + return false; + } + if (!msg.val()) { + return false; + } + conn.send(msg.val()); + msg.val(""); + return false + }); + + if (window["WebSocket"]) { + conn = new WebSocket("ws://{{$}}/ws"); + conn.onclose = function(evt) { + appendLog($("<div><b>Connection closed.</b></div>")) + } + conn.onmessage = function(evt) { + appendLog($("<pre/>").text(evt.data)) + } + } else { + appendLog($("<div><b>Your browser does not support WebSockets.</b></div>")) + } + }); +</script> +<style type="text/css"> +html { + overflow: hidden; +} + +body { + overflow: hidden; + padding: 0; + margin: 0; + width: 100%; + height: 100%; + background: gray; +} + +#log { + background: white; + margin: 0; + padding: 0.5em 0.5em 0.5em 0.5em; + position: absolute; + top: 0.5em; + left: 0.5em; + right: 0.5em; + bottom: 3em; + overflow: auto; +} + +#log pre { + margin: 0; +} + +#form { + padding: 0 0.5em 0 0.5em; + margin: 0; + position: absolute; + bottom: 1em; + left: 0px; + width: 100%; + overflow: hidden; +} + +</style> +</head> +<body> +<div id="log"></div> +<form id="form"> + <input type="submit" value="Send" /> + <input type="text" id="msg" size="64"/> +</form> +</body> +</html> diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go new file mode 100644 index 000000000..f3f022edb --- /dev/null +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/command/main.go @@ -0,0 +1,188 @@ +// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bufio" + "flag" + "io" + "log" + "net/http" + "os" + "os/exec" + "text/template" + "time" + + "github.com/gorilla/websocket" +) + +var ( + addr = flag.String("addr", "127.0.0.1:8080", "http service address") + cmdPath string + homeTempl = template.Must(template.ParseFiles("home.html")) +) + +const ( + // Time allowed to write a message to the peer. + writeWait = 10 * time.Second + + // Maximum message size allowed from peer. + maxMessageSize = 8192 + + // Time allowed to read the next pong message from the peer. + pongWait = 60 * time.Second + + // Send pings to peer with this period. Must be less than pongWait. + pingPeriod = (pongWait * 9) / 10 +) + +func pumpStdin(ws *websocket.Conn, w io.Writer) { + defer ws.Close() + ws.SetReadLimit(maxMessageSize) + ws.SetReadDeadline(time.Now().Add(pongWait)) + ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil }) + for { + _, message, err := ws.ReadMessage() + if err != nil { + break + } + message = append(message, '\n') + if _, err := w.Write(message); err != nil { + break + } + } +} + +func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) { + defer func() { + ws.Close() + close(done) + }() + s := bufio.NewScanner(r) + for s.Scan() { + ws.SetWriteDeadline(time.Now().Add(writeWait)) + if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil { + break + } + } + if s.Err() != nil { + log.Println("scan:", s.Err()) + } +} + +func ping(ws *websocket.Conn, done chan struct{}) { + ticker := time.NewTicker(pingPeriod) + defer ticker.Stop() + for { + select { + case <-ticker.C: + if err := ws.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(writeWait)); err != nil { + log.Println("ping:", err) + } + case <-done: + return + } + } +} + +func internalError(ws *websocket.Conn, msg string, err error) { + log.Println(msg, err) + ws.WriteMessage(websocket.TextMessage, []byte("Internal server error.")) +} + +var upgrader = websocket.Upgrader{} + +func serveWs(w http.ResponseWriter, r *http.Request) { + ws, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Println("upgrade:", err) + return + } + + defer ws.Close() + + outr, outw, err := os.Pipe() + if err != nil { + internalError(ws, "stdout:", err) + return + } + defer outr.Close() + defer outw.Close() + + inr, inw, err := os.Pipe() + if err != nil { + internalError(ws, "stdin:", err) + return + } + defer inr.Close() + defer inw.Close() + + proc, err := os.StartProcess(cmdPath, flag.Args(), &os.ProcAttr{ + Files: []*os.File{inr, outw, outw}, + }) + if err != nil { + internalError(ws, "start:", err) + return + } + + inr.Close() + outw.Close() + + stdoutDone := make(chan struct{}) + go pumpStdout(ws, outr, stdoutDone) + go ping(ws, stdoutDone) + + pumpStdin(ws, inw) + + // Some commands will exit when stdin is closed. + inw.Close() + + // Other commands need a bonk on the head. + if err := proc.Signal(os.Interrupt); err != nil { + log.Println("inter:", err) + } + + select { + case <-stdoutDone: + case <-time.After(time.Second): + // A bigger bonk on the head. + if err := proc.Signal(os.Kill); err != nil { + log.Println("term:", err) + } + <-stdoutDone + } + + if _, err := proc.Wait(); err != nil { + log.Println("wait:", err) + } +} + +func serveHome(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.Error(w, "Not found", 404) + return + } + if r.Method != "GET" { + http.Error(w, "Method not allowed", 405) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + homeTempl.Execute(w, r.Host) +} + +func main() { + flag.Parse() + if len(flag.Args()) < 1 { + log.Fatal("must specify at least one argument") + } + var err error + cmdPath, err = exec.LookPath(flag.Args()[0]) + if err != nil { + log.Fatal(err) + } + http.HandleFunc("/", serveHome) + http.HandleFunc("/ws", serveWs) + log.Fatal(http.ListenAndServe(*addr, nil)) +} diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md new file mode 100644 index 000000000..6ad79ed76 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/README.md @@ -0,0 +1,17 @@ +# Client and server example + +This example shows a simple client and server. + +The server echoes messages sent to it. The client sends a message every second +and prints all messages received. + +To run the example, start the server: + + $ go run server.go + +Next, start the client: + + $ go run client.go + +The server includes a simple web client. To use the client, open +http://127.0.0.1:8080 in the browser and follow the instructions on the page. diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go new file mode 100644 index 000000000..45a023175 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/client.go @@ -0,0 +1,55 @@ +// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import ( + "flag" + "log" + "net/url" + "time" + + "github.com/gorilla/websocket" +) + +var addr = flag.String("addr", "localhost:8080", "http service address") + +func main() { + flag.Parse() + log.SetFlags(0) + + u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"} + log.Printf("connecting to %s", u.String()) + + c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) + if err != nil { + log.Fatal("dial:", err) + } + defer c.Close() + + go func() { + defer c.Close() + for { + _, message, err := c.ReadMessage() + if err != nil { + log.Println("read:", err) + break + } + log.Printf("recv: %s", message) + } + }() + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for t := range ticker.C { + err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) + if err != nil { + log.Println("write:", err) + break + } + } +} diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go new file mode 100644 index 000000000..a685b0974 --- /dev/null +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/echo/server.go @@ -0,0 +1,132 @@ +// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import ( + "flag" + "html/template" + "log" + "net/http" + + "github.com/gorilla/websocket" +) + +var addr = flag.String("addr", "localhost:8080", "http service address") + +var upgrader = websocket.Upgrader{} // use default options + +func echo(w http.ResponseWriter, r *http.Request) { + c, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Print("upgrade:", err) + return + } + defer c.Close() + for { + mt, message, err := c.ReadMessage() + if err != nil { + log.Println("read:", err) + break + } + log.Printf("recv: %s", message) + err = c.WriteMessage(mt, message) + if err != nil { + log.Println("write:", err) + break + } + } +} + +func home(w http.ResponseWriter, r *http.Request) { + homeTemplate.Execute(w, "ws://"+r.Host+"/echo") +} + +func main() { + flag.Parse() + log.SetFlags(0) + http.HandleFunc("/echo", echo) + http.HandleFunc("/", home) + log.Fatal(http.ListenAndServe(*addr, nil)) +} + +var homeTemplate = template.Must(template.New("").Parse(` +<!DOCTYPE html> +<head> +<meta charset="utf-8"> +<script> +window.addEventListener("load", function(evt) { + + var output = document.getElementById("output"); + var input = document.getElementById("input"); + var ws; + + var print = function(message) { + var d = document.createElement("div"); + d.innerHTML = message; + output.appendChild(d); + }; + + document.getElementById("open").onclick = function(evt) { + if (ws) { + return false; + } + ws = new WebSocket("{{.}}"); + ws.onopen = function(evt) { + print("OPEN"); + } + ws.onclose = function(evt) { + print("CLOSE"); + ws = null; + } + ws.onmessage = function(evt) { + print("RESPONSE: " + evt.data); + } + ws.onerror = function(evt) { + print("ERROR: " + evt.data); + } + return false; + }; + + document.getElementById("send").onclick = function(evt) { + if (!ws) { + return false; + } + print("SEND: " + input.value); + ws.send(input.value); + return false; + }; + + document.getElementById("close").onclick = function(evt) { + if (!ws) { + return false; + } + ws.close(); + return false; + }; + +}); +</script> +</head> +<body> +<table> +<tr><td valign="top" width="50%"> +<p>Click "Open" to create a connection to the server, +"Send" to send a message to the server and "Close" to close the connection. +You can change the message and send multiple times. +<p> +<form> +<button id="open">Open</button> +<button id="close">Close</button> +<p><input id="input" type="text" value="Hello world!"> +<button id="send">Send</button> +</form> +</td><td valign="top" width="50%"> +<div id="output"></div> +</td></tr></table> +</body> +</html> +`)) |