예제 #1
0
파일: ws.go 프로젝트: dmeulen/fabio
func wsHandler(client *websocket.Conn) {
	r := client.Request()
	t := target(r)
	if t == nil {
		client.WriteClose(http.StatusNotFound)
		return
	}

	logerr := func(err error) {
		if err != nil && err != io.EOF {
			log.Printf("[INFO] WS error for %s. %s", r.URL, err)
		}
	}

	// dial the server
	origin := r.Header.Get("Origin")
	targetURL := "ws://" + t.URL.Host + r.RequestURI
	server, err := websocket.Dial(targetURL, "", origin)
	if err != nil {
		logerr(err)
		return
	}

	// send data from client to server
	cerr := make(chan error)
	go func() {
		_, err := io.Copy(server, client)
		cerr <- err
	}()

	// send data from server to client
	serr := make(chan error)
	go func() {
		_, err = io.Copy(client, server)
		serr <- err
	}()

	// wait for either server or client to exit
	// and then close the other side
	start := time.Now()
	select {
	case err := <-cerr:
		logerr(err)
		server.Close()
	case err := <-serr:
		logerr(err)
		client.Close()
	}
	t.Timer.UpdateSince(start)
}
예제 #2
0
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", addr, err)
			break
		}
	}
	log.Printf("ws disconnect on %s", addr)
}