Skip to content

Commit

Permalink
Issue #9: Add websocket support to demo clients
Browse files Browse the repository at this point in the history
* Add websocket support to demo/server
* Add simple websocket client in demo/wsclient
  • Loading branch information
magiconair committed Nov 11, 2015
1 parent 872c191 commit 6102bfd
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 8 deletions.
56 changes: 48 additions & 8 deletions demo/server/server.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Package server provides a sample HTTP web server which registers
// itself in consul using one or more URL prefixes to demonstrate and
// Package server provides a sample HTTP/Websocket server which registers
// itself in consul using one or more url prefixes to demonstrate and
// test the automatic fabio routing table update.
//
// During startup the server performs the following steps:
Expand All @@ -12,17 +12,24 @@
// tag per prefix
// * Install a signal handler to deregister the service on exit
//
// If the protocol is set to "ws" the registered endpoints function
// as websocket echo servers.
//
// Example:
//
// # http server
// ./server -addr 127.0.0.1:5000 -name svc-a -prefix /foo,/bar
// ./server -addr 127.0.0.1:6000 -name svc-b -prefix /baz,/bar
// ./server -addr 127.0.0.1:5001 -name svc-b -prefix /baz,/bar
//
// # websocket server
// ./server -addr 127.0.0.1:6000 -name ws-a -prefix /echo1,/echo2 -proto ws
//
// This used to be hosted under https://github.com/magiconair/fabio-example
package main

import (
"flag"
"fmt"
"io"
"log"
"net"
"net/http"
Expand All @@ -33,14 +40,16 @@ import (
"strings"

"github.com/eBay/fabio/_third_party/github.com/hashicorp/consul/api"
"github.com/eBay/fabio/_third_party/golang.org/x/net/websocket"
)

func main() {
var addr, consul, name, prefix string
var addr, consul, name, prefix, proto string
flag.StringVar(&addr, "addr", "127.0.0.1:5000", "host:port of the service")
flag.StringVar(&consul, "consul", "127.0.0.1:8500", "host:port of the consul agent")
flag.StringVar(&name, "name", filepath.Base(os.Args[0]), "name of the service")
flag.StringVar(&prefix, "prefix", "", "comma-sep list of host/path prefixes to register")
flag.StringVar(&proto, "proto", "http", "protocol for endpoints: http or ws")
flag.Parse()

if prefix == "" {
Expand All @@ -51,9 +60,16 @@ func main() {
// register prefixes
prefixes := strings.Split(prefix, ",")
for _, p := range prefixes {
http.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Serving %s from %s on %s\n", r.RequestURI, name, addr)
})
switch proto {
case "http":
http.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Serving %s from %s on %s\n", r.RequestURI, name, addr)
})
case "ws":
http.Handle(p, websocket.Handler(EchoServer))
default:
log.Fatal("Invalid protocol ", proto)
}
}

// start http server
Expand Down Expand Up @@ -123,3 +139,27 @@ func main() {
}
log.Printf("Deregistered service %q in consul", name)
}

func EchoServer(ws *websocket.Conn) {
addr := ws.LocalAddr().String()
pfx := []byte("[" + addr + "] ")

log.Printf("ws connect on %s", addr)

// the following could be done with io.Copy(ws, ws)
// but I want to add some meta data
var msg = make([]byte, 1024)
for {
n, err := ws.Read(msg)
if err != nil && err != io.EOF {
log.Printf("ws error on %s. %s", addr, err)
break
}
_, err = ws.Write(append(pfx, msg[:n]...))
if err != nil && err != io.EOF {
log.Printf("ws error on %s%s. %s", addr, err)
break
}
}
log.Printf("ws disconnect on %s", addr)
}
1 change: 1 addition & 0 deletions demo/wsclient/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wsclient
50 changes: 50 additions & 0 deletions demo/wsclient/wsclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Package wsclient implements a simple web socket client
// which reads lines from stdin and sends them to the
// websocket url.
package main

import (
"bufio"
"flag"
"fmt"
"log"
"os"

"github.com/eBay/fabio/_third_party/golang.org/x/net/websocket"
)

func main() {
var url, origin string
flag.StringVar(&url, "url", "ws://127.0.0.1:9999/echo", "websocket URL")
flag.StringVar(&origin, "origin", "http://localhost/", "origin header")
flag.Parse()

if url == "" {
flag.Usage()
os.Exit(1)
}

ws, err := websocket.Dial(url, "", origin)
if err != nil {
log.Fatal(err)
}

go func() {
var msg = make([]byte, 512)
for {
n, err := ws.Read(msg)
if err != nil {
log.Fatal(err)
}
fmt.Printf("R: %s\nS: ", msg[:n])
}
}()

fmt.Print("S: ")
sc := bufio.NewScanner(os.Stdin)
for sc.Scan() {
if _, err := ws.Write(sc.Bytes()); err != nil {
log.Fatal(err)
}
}
}

0 comments on commit 6102bfd

Please sign in to comment.