veyron/servives/wsprd: update to use ListenX.

Change-Id: I1a3e7a98bb6bd2b98b6de2cf982105e543b7de94
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index a8ff3b3..c5fcc7c 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -340,6 +340,7 @@
 			s.proxyListenLoop(ln, ep, proxy)
 			s.active.Done()
 		}(pln, pep, listenSpec.Proxy)
+		s.listeners[pln] = nil
 		s.publisher.AddServer(s.publishEP(pep), s.servesMountTable)
 	} else {
 		s.publisher.AddServer(s.publishEP(ep), s.servesMountTable)
@@ -521,6 +522,7 @@
 	// flows will continue until they terminate naturally.
 	nListeners := len(s.listeners)
 	errCh := make(chan error, nListeners)
+
 	for ln, dhcpl := range s.listeners {
 		go func(ln stream.Listener) {
 			errCh <- ln.Close()
diff --git a/services/wsprd/app/app.go b/services/wsprd/app/app.go
index afa3c18..d09051e 100644
--- a/services/wsprd/app/app.go
+++ b/services/wsprd/app/app.go
@@ -93,6 +93,9 @@
 	// The runtime to use to create new clients.
 	rt veyron2.Runtime
 
+	// The ipc.ListenSpec to use with server.Listen
+	listenSpec *ipc.ListenSpec
+
 	// Used to generate unique ids for requests initiated by the proxy.
 	// These ids will be even so they don't collide with the ids generated
 	// by the client.
@@ -128,7 +131,7 @@
 // javascript server. veyronProxyEP is an endpoint for the veyron proxy to serve through.  It can't be empty.
 // opts are any options that should be passed to the rt.New(), such as the mounttable root.
 func NewController(writerCreator func(id int64) lib.ClientWriter,
-	veyronProxyEP string, opts ...veyron2.ROpt) (*Controller, error) {
+	listenSpec *ipc.ListenSpec, opts ...veyron2.ROpt) (*Controller, error) {
 	r, err := rt.New(opts...)
 	if err != nil {
 		return nil, err
@@ -143,7 +146,7 @@
 		logger:        r.Logger(),
 		client:        client,
 		writerCreator: writerCreator,
-		veyronProxyEP: veyronProxyEP,
+		listenSpec:    listenSpec,
 		idStore:       identity.NewJSPublicIDHandles(),
 	}
 	controller.setup()
@@ -266,6 +269,7 @@
 	c.logger.VI(0).Info("Cleaning up websocket")
 	c.Lock()
 	defer c.Unlock()
+
 	for _, stream := range c.outstandingStreams {
 		stream.end()
 	}
@@ -409,7 +413,7 @@
 	if server, ok := c.servers[serverId]; ok {
 		return server, nil
 	}
-	server, err := server.NewServer(serverId, c.veyronProxyEP, c)
+	server, err := server.NewServer(serverId, c.listenSpec, c)
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/wsprd/app/app_test.go b/services/wsprd/app/app_test.go
index ae62d84..5e4abd0 100644
--- a/services/wsprd/app/app_test.go
+++ b/services/wsprd/app/app_test.go
@@ -5,6 +5,7 @@
 	"fmt"
 	"reflect"
 	"testing"
+
 	"veyron.io/veyron/veyron/services/wsprd/lib"
 	"veyron.io/veyron/veyron/services/wsprd/lib/testwriter"
 	"veyron.io/veyron/veyron/services/wsprd/signature"
@@ -19,6 +20,7 @@
 	vom_wiretype "veyron.io/veyron/veyron2/vom/wiretype"
 	"veyron.io/veyron/veyron2/wiretype"
 
+	"veyron.io/veyron/veyron/profiles"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/proxy"
 	mounttable "veyron.io/veyron/veyron/services/mounttable/lib"
 )
@@ -151,7 +153,9 @@
 		return
 	}
 	defer s.Stop()
-	controller, err := NewController(nil, "mockVeyronProxyEP")
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "mockVeyronProxyEP"
+	controller, err := NewController(nil, &spec)
 
 	if err != nil {
 		t.Errorf("Failed to create controller: %v", err)
@@ -185,7 +189,9 @@
 	}
 	defer s.Stop()
 
-	controller, err := NewController(nil, "mockVeyronProxyEP")
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "mockVeyronProxyEP"
+	controller, err := NewController(nil, &spec)
 
 	if err != nil {
 		t.Errorf("unable to create controller: %v", err)
@@ -304,8 +310,10 @@
 	writerCreator := func(int64) lib.ClientWriter {
 		return &writer
 	}
-	controller, err := NewController(writerCreator, "/"+proxyEndpoint,
-		veyron2.NamespaceRoots{"/" + endpoint.String()})
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "/" + proxyEndpoint
+	controller, err := NewController(writerCreator, &spec, veyron2.NamespaceRoots{"/" + endpoint.String()})
+
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/wsprd/ipc/server/server.go b/services/wsprd/ipc/server/server.go
index 3f4c73d..55a21c5 100644
--- a/services/wsprd/ipc/server/server.go
+++ b/services/wsprd/ipc/server/server.go
@@ -7,15 +7,15 @@
 	"fmt"
 	"sync"
 
+	vsecurity "veyron.io/veyron/veyron/security"
+	"veyron.io/veyron/veyron/services/wsprd/lib"
+	"veyron.io/veyron/veyron/services/wsprd/signature"
+
 	"veyron.io/veyron/veyron2"
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/verror"
 	"veyron.io/veyron/veyron2/vlog"
-
-	vsecurity "veyron.io/veyron/veyron/security"
-	"veyron.io/veyron/veyron/services/wsprd/lib"
-	"veyron.io/veyron/veyron/services/wsprd/signature"
 )
 
 type Flow struct {
@@ -94,6 +94,9 @@
 type Server struct {
 	mu sync.Mutex
 
+	// The ipc.ListenSpec to use with server.Listen
+	listenSpec *ipc.ListenSpec
+
 	// The server that handles the ipc layer.  Listen on this server is
 	// lazily started.
 	server ipc.Server
@@ -109,20 +112,17 @@
 	id     uint64
 	helper ServerHelper
 
-	// The proxy to listen through.
-	veyronProxy string
-
 	// The set of outstanding server requests.
 	outstandingServerRequests map[int64]chan *serverRPCReply
 
 	outstandingAuthRequests map[int64]chan error
 }
 
-func NewServer(id uint64, veyronProxy string, helper ServerHelper) (*Server, error) {
+func NewServer(id uint64, listenSpec *ipc.ListenSpec, helper ServerHelper) (*Server, error) {
 	server := &Server{
 		id:                        id,
 		helper:                    helper,
-		veyronProxy:               veyronProxy,
+		listenSpec:                listenSpec,
 		outstandingServerRequests: make(map[int64]chan *serverRPCReply),
 		outstandingAuthRequests:   make(map[int64]chan error),
 	}
@@ -252,8 +252,7 @@
 	}
 
 	if s.endpoint == "" {
-		endpoint, err := s.server.Listen("veyron", s.veyronProxy)
-
+		endpoint, err := s.server.ListenX(s.listenSpec)
 		if err != nil {
 			return "", err
 		}
diff --git a/services/wsprd/wspr.go b/services/wsprd/wspr.go
index 7bab7ce..c169046 100644
--- a/services/wsprd/wspr.go
+++ b/services/wsprd/wspr.go
@@ -6,17 +6,17 @@
 	"veyron.io/veyron/veyron/lib/signals"
 	"veyron.io/veyron/veyron/services/wsprd/wspr"
 	"veyron.io/veyron/veyron2/rt"
+	// TODO(cnicolaou,benj): figure out how to support roaming as a chrome plugi
+	"veyron.io/veyron/veyron/profiles/roaming"
 )
 
 func main() {
-	port := flag.Int("port", 8124, "Port to listen on.")
-	veyronProxy := flag.String("vproxy", "", "The endpoint for the veyron proxy to publish on. This must be set.")
 	identd := flag.String("identd", "", "The endpoint for the identd server.  This must be set.")
 	flag.Parse()
 
 	rt.Init()
 
-	proxy := wspr.NewWSPR(*port, *veyronProxy, *identd)
+	proxy := wspr.NewWSPR(*roaming.ListenSpec, *identd)
 	defer proxy.Shutdown()
 	go func() {
 		proxy.Run()
diff --git a/services/wsprd/wspr/pipe.go b/services/wsprd/wspr/pipe.go
index f4e9894..85f993d 100644
--- a/services/wsprd/wspr/pipe.go
+++ b/services/wsprd/wspr/pipe.go
@@ -129,7 +129,7 @@
 		// TODO(bjornick): Send an error to the client when all of the identity stuff is set up.
 	}
 
-	pipe.controller, err = app.NewController(creator, wspr.veyronProxyEP, veyron2.RuntimeID(id))
+	pipe.controller, err = app.NewController(creator, &wspr.listenSpec, veyron2.RuntimeID(id))
 
 	if err != nil {
 		wspr.rt.Logger().Errorf("Could not create controller: %v", err)
diff --git a/services/wsprd/wspr/wspr.go b/services/wsprd/wspr/wspr.go
index 727807d..3a62cd6 100644
--- a/services/wsprd/wspr/wspr.go
+++ b/services/wsprd/wspr/wspr.go
@@ -21,17 +21,20 @@
 	"fmt"
 	"io"
 	"log"
+	"net"
 	"net/http"
 	_ "net/http/pprof"
 	"sync"
 	"time"
 
-	veyron_identity "veyron.io/veyron/veyron/services/identity"
-	"veyron.io/veyron/veyron/services/wsprd/identity"
 	"veyron.io/veyron/veyron2"
+	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/vlog"
+
+	veyron_identity "veyron.io/veyron/veyron/services/identity"
+	"veyron.io/veyron/veyron/services/wsprd/identity"
 )
 
 const (
@@ -48,9 +51,8 @@
 	tlsCert        *tls.Certificate
 	rt             veyron2.Runtime
 	logger         vlog.Logger
-	port           int
+	listenSpec     ipc.ListenSpec
 	identdEP       string
-	veyronProxyEP  string
 	idManager      *identity.IDManager
 	blesserService veyron_identity.OAuthBlesser
 	pipes          map[*http.Request]*pipe
@@ -91,8 +93,12 @@
 	// registered patterns, not just the URL with Path == "/".'
 	// (http://golang.org/pkg/net/http/#ServeMux)
 	http.Handle("/", http.NotFoundHandler())
-	ctx.logger.VI(1).Infof("Listening on port %d.", ctx.port)
-	httpErr := http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", ctx.port), nil)
+	_, port, err := net.SplitHostPort(ctx.listenSpec.Address)
+	if err != nil {
+		log.Fatal("Failed to extra port from %q", ctx.listenSpec.Address)
+	}
+	ctx.logger.VI(1).Infof("Listening on port %d.", port)
+	httpErr := http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", port), nil)
 	if httpErr != nil {
 		log.Fatalf("Failed to HTTP serve: %s", httpErr)
 	}
@@ -109,8 +115,8 @@
 }
 
 // Creates a new WebSocket Proxy object.
-func NewWSPR(port int, veyronProxyEP, identdEP string, opts ...veyron2.ROpt) *WSPR {
-	if veyronProxyEP == "" {
+func NewWSPR(listenSpec ipc.ListenSpec, identdEP string, opts ...veyron2.ROpt) *WSPR {
+	if listenSpec.Proxy == "" {
 		log.Fatalf("a veyron proxy must be set")
 	}
 	if identdEP == "" {
@@ -128,13 +134,12 @@
 		log.Fatalf("identity.NewIDManager failed: %s", err)
 	}
 
-	return &WSPR{port: port,
-		veyronProxyEP: veyronProxyEP,
-		identdEP:      identdEP,
-		rt:            newrt,
-		logger:        newrt.Logger(),
-		idManager:     idManager,
-		pipes:         map[*http.Request]*pipe{},
+	return &WSPR{listenSpec: listenSpec,
+		identdEP:  identdEP,
+		rt:        newrt,
+		logger:    newrt.Logger(),
+		idManager: idManager,
+		pipes:     map[*http.Request]*pipe{},
 	}
 }
 
diff --git a/services/wsprd/wspr/wspr_test.go b/services/wsprd/wspr/wspr_test.go
index 8981d74..ffeb1fc 100644
--- a/services/wsprd/wspr/wspr_test.go
+++ b/services/wsprd/wspr/wspr_test.go
@@ -13,6 +13,8 @@
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/vdl/vdlutil"
+
+	"veyron.io/veyron/veyron/profiles"
 )
 
 // BEGIN MOCK BLESSER SERVICE
@@ -53,7 +55,9 @@
 // END MOCK BLESSER SERVICE
 
 func setup(t *testing.T) (*WSPR, func()) {
-	wspr := NewWSPR(0, "/mock/proxy", "/mock/identd")
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "/mock/proxy"
+	wspr := NewWSPR(spec, "/mock/identd")
 	providerId := wspr.rt.Identity()
 
 	wspr.blesserService = newMockBlesserService(providerId)