func main() { // set GPIO25 to output mode pin, err := gpio.OpenPin(rpi.GPIO25, gpio.ModeOutput) if err != nil { fmt.Printf("Error opening pin! %s\n", err) return } // turn the led off on exit c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { for _ = range c { fmt.Printf("\nClearing and unexporting the pin.\n") pin.Clear() pin.Close() os.Exit(0) } }() go buttonHandler(pin) // http listen //http.Handle("/button", websocket.Handler(EchoServer)) http.HandleFunc("/button", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{Handler: websocket.Handler(EchoServer)} s.ServeHTTP(w, req) }) http.ListenAndServe(":8080", nil) }
// Authenticate a websocket before servicing it. func AuthWebSocketHandler(h websocket.Handler) http.HandlerFunc { hndler := func(w http.ResponseWriter, r *http.Request) { if auth.TLSserver != nil && auth.Enabled { clive, err := r.Cookie("clive") if err != nil { cmd.Warn("wax/auth: no cookie: %s", err) http.Error(w, "auth failed", 403) return } toks := strings.SplitN(string(clive.Value), ":", 2) if len(toks) < 2 { cmd.Warn("wax/auth: wrong cookie") http.Error(w, "auth failed", 403) return } ch, resp := toks[0], toks[1] u, ok := auth.ChallengeResponseOk("wax", ch, resp) if !ok { cmd.Warn("wax/auth: failed for %s", u) http.Error(w, "auth failed", 403) return } } s := websocket.Server{Handler: h, Handshake: checkOrigin} s.ServeHTTP(w, r) } return hndler }
// ServeHTTP will serve up connections as a websocket for the // debug-log API. // // Args for the HTTP request are as follows: // includeEntity -> []string - lists entity tags to include in the response // - tags may finish with a '*' to match a prefix e.g.: unit-mysql-*, machine-2 // - if none are set, then all lines are considered included // includeModule -> []string - lists logging modules to include in the response // - if none are set, then all lines are considered included // excludeEntity -> []string - lists entity tags to exclude from the response // - as with include, it may finish with a '*' // excludeModule -> []string - lists logging modules to exclude from the response // limit -> uint - show *at most* this many lines // backlog -> uint // - go back this many lines from the end before starting to filter // - has no meaning if 'replay' is true // level -> string one of [TRACE, DEBUG, INFO, WARNING, ERROR] // replay -> string - one of [true, false], if true, start the file from the start func (h *debugLogHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { server := websocket.Server{ Handler: func(conn *websocket.Conn) { socket := &debugLogSocketImpl{conn} defer socket.Close() logger.Infof("debug log handler starting") // Validate before authenticate because the authentication is // dependent on the state connection that is determined during the // validation. st, _, err := h.ctxt.stateForRequestAuthenticatedUser(req) if err != nil { socket.sendError(err) return } params, err := readDebugLogParams(req.URL.Query()) if err != nil { socket.sendError(err) return } if err := h.handle(st, params, socket, h.stop); err != nil { if isBrokenPipe(err) { logger.Tracef("debug-log handler stopped (client disconnected)") } else { logger.Errorf("debug-log handler error: %v", err) } } }, } server.ServeHTTP(w, req) }
func (s *Server) wsContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := parseForm(r); err != nil { return err } if vars == nil { return fmt.Errorf("Missing parameter") } cont, err := s.daemon.Get(vars["name"]) if err != nil { return err } h := websocket.Handler(func(ws *websocket.Conn) { defer ws.Close() wsAttachWithLogsConfig := &daemon.ContainerWsAttachWithLogsConfig{ InStream: ws, OutStream: ws, ErrStream: ws, Logs: boolValue(r, "logs"), Stream: boolValue(r, "stream"), } if err := s.daemon.ContainerWsAttachWithLogs(cont, wsAttachWithLogsConfig); err != nil { logrus.Errorf("Error attaching websocket: %s", err) } }) ws := websocket.Server{Handler: h, Handshake: nil} ws.ServeHTTP(w, r) return nil }
func (srv *Server) apiHandler(w http.ResponseWriter, req *http.Request) { addCount := func(delta int64) { atomic.AddInt64(&srv.connCount, delta) } addCount(1) defer addCount(-1) connectionID := atomic.AddUint64(&srv.lastConnectionID, 1) apiObserver := srv.newObserver() apiObserver.Join(req, connectionID) defer apiObserver.Leave() wsServer := websocket.Server{ Handler: func(conn *websocket.Conn) { modelUUID := req.URL.Query().Get(":modeluuid") logger.Tracef("got a request for model %q", modelUUID) if err := srv.serveConn(conn, modelUUID, apiObserver, req.Host); err != nil { logger.Errorf("error serving RPCs: %v", err) } }, } wsServer.ServeHTTP(w, req) }
func (s *router) wsContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } containerName := vars["name"] if !s.daemon.Exists(containerName) { return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) } h := websocket.Handler(func(ws *websocket.Conn) { defer ws.Close() wsAttachWithLogsConfig := &daemon.ContainerWsAttachWithLogsConfig{ InStream: ws, OutStream: ws, ErrStream: ws, Logs: httputils.BoolValue(r, "logs"), Stream: httputils.BoolValue(r, "stream"), } if err := s.daemon.ContainerWsAttachWithLogs(containerName, wsAttachWithLogsConfig); err != nil { logrus.Errorf("Error attaching websocket: %s", err) } }) ws := websocket.Server{Handler: h, Handshake: nil} ws.ServeHTTP(w, r) return nil }
// WSHandler is websocket end point func WSHandler(w http.ResponseWriter, r *http.Request) { s := websocket.Server{Handler: websocket.Handler( func(ws *websocket.Conn) { connection := &webSocketConnection{ws: ws} // add connection manager.AddConnection(connection) defer func() { // delete connection manager.DelConnection(connection) }() for { // receive message message := new(Message) err := websocket.JSON.Receive(ws, message) if err != nil { // close event if err == io.EOF { return } log.Println(err) } log.Printf("client: %#v\n", message) } }), } s.ServeHTTP(w, r) }
// ServeHTTP implements the http.Handler interface. func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { server := websocket.Server{ Handler: func(socket *websocket.Conn) { defer socket.Close() st, entity, err := h.ctxt.stateForRequestAuthenticatedAgent(req) if err != nil { h.sendError(socket, req, err) return } tag := entity.Tag() // Note that this endpoint is agent-only. Thus the only // callers will necessarily provide their Juju version. // // This would be a problem if non-Juju clients (e.g. the // GUI) could use this endpoint since we require that the // *Juju* version be provided as part of the request. Any // attempt to open this endpoint to broader access must // address this caveat appropriately. ver, err := jujuClientVersionFromReq(req) if err != nil { h.sendError(socket, req, err) return } filePrefix := st.ModelUUID() + " " + tag.String() + ":" dbLogger := state.NewDbLogger(st, tag, ver) defer dbLogger.Close() // If we get to here, no more errors to report, so we report a nil // error. This way the first line of the socket is always a json // formatted simple error. h.sendError(socket, req, nil) logCh := h.receiveLogs(socket) for { select { case <-h.ctxt.stop(): return case m := <-logCh: fileErr := h.logToFile(filePrefix, m) if fileErr != nil { logger.Errorf("logging to logsink.log failed: %v", fileErr) } level, _ := loggo.ParseLevel(m.Level) dbErr := dbLogger.Log(m.Time, m.Module, m.Location, level, m.Message) if dbErr != nil { logger.Errorf("logging to DB failed: %v", err) } if fileErr != nil || dbErr != nil { return } } } }, } server.ServeHTTP(w, req) }
func (srv *Server) serveAPI(w http.ResponseWriter, req *http.Request) { wsServer := websocket.Server{ Handler: func(conn *websocket.Conn) { srv.serveConn(conn, req.URL.Query().Get(":modeluuid")) }, } wsServer.ServeHTTP(w, req) }
func (s *containerRouter) wsContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } containerName := vars["name"] var keys []byte var err error detachKeys := r.FormValue("detachKeys") if detachKeys != "" { keys, err = term.ToBytes(detachKeys) if err != nil { logrus.Warnf("Invalid escape keys provided (%s) using default : ctrl-p ctrl-q", detachKeys) } } done := make(chan struct{}) started := make(chan struct{}) setupStreams := func() (io.ReadCloser, io.Writer, io.Writer, error) { wsChan := make(chan *websocket.Conn) h := func(conn *websocket.Conn) { wsChan <- conn <-done } srv := websocket.Server{Handler: h, Handshake: nil} go func() { close(started) srv.ServeHTTP(w, r) }() conn := <-wsChan return conn, conn, conn, nil } attachConfig := &backend.ContainerAttachConfig{ GetStreams: setupStreams, Logs: httputils.BoolValue(r, "logs"), Stream: httputils.BoolValue(r, "stream"), DetachKeys: keys, UseStdin: true, UseStdout: true, UseStderr: true, MuxStreams: false, // TODO: this should be true since it's a single stream for both stdout and stderr } err = s.backend.ContainerAttach(containerName, attachConfig) close(done) select { case <-started: logrus.Errorf("Error attaching websocket: %s", err) return nil default: } return err }
func (this *webScoketAdapter) webScoketHandlerAdapter(request *http.Request, pathFragments map[string]string, reply *Reply) { reply.startWebSocket() server := websocket.Server{Handler: func(conn *websocket.Conn) { defer func() { conn.Close() }() this.handler(request, pathFragments, &WebSocketReply{conn}) }, Handshake: checkOrigin} server.ServeHTTP(reply.w, request) }
// ServeHTTP implements the http.Handler interface. func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { server := websocket.Server{ Handler: func(socket *websocket.Conn) { defer socket.Close() // Validate before authenticate because the authentication is // dependent on the state connection that is determined during the // validation. stateWrapper, err := h.validateEnvironUUID(req) if err != nil { if errErr := h.sendError(socket, err); errErr != nil { // Log at DEBUG so that in a standard environment // logs cant't fill up with auth errors for // unauthenticated connections. logger.Debugf("error sending logsink error: %v", errErr) } return } defer stateWrapper.cleanup() tag, err := stateWrapper.authenticateAgent(req) if err != nil { if errErr := h.sendError(socket, errors.Errorf("auth failed: %v", err)); errErr != nil { // DEBUG used as above. logger.Debugf("error sending logsink error: %v", errErr) } return } // If we get to here, no more errors to report, so we report a nil // error. This way the first line of the socket is always a json // formatted simple error. if err := h.sendError(socket, nil); err != nil { logger.Errorf("failed to send nil error at start of connection") return } dbLogger := state.NewDbLogger(stateWrapper.state, tag) defer dbLogger.Close() var m LogMessage for { if err := websocket.JSON.Receive(socket, &m); err != nil { if err != io.EOF { logger.Errorf("error while receiving logs: %v", err) } break } if err := dbLogger.Log(m.Time, m.Module, m.Location, m.Level, m.Message); err != nil { logger.Errorf("logging to DB failed: %v", err) break } } }} server.ServeHTTP(w, req) }
func (this *Transport) Listen(ch drs.ConnectionHandler) error { http.HandleFunc("/socket", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{ Handler: websocket.Handler(func(ws *websocket.Conn) { ch(ws) }), } s.ServeHTTP(w, req) }) return http.ListenAndServe(":12000", nil) }
// WEBSOCKET adds a WebSocket route > handler to the router. Use the helper // function FromContextWebsocket() to extract the websocket.Conn in your HandlerFunc // from the context. func (r *Router) WEBSOCKET(path string, h ctxhttp.HandlerFunc) { r.GET(path, func(ctx context.Context, w http.ResponseWriter, r *http.Request) (err error) { wss := websocket.Server{ Handler: func(ws *websocket.Conn) { w.WriteHeader(http.StatusSwitchingProtocols) err = h(withContextWebsocket(ctx, ws), w, r) }, } wss.ServeHTTP(w, r) return err }) }
// This example demonstrates a trivial echo server. func main() { fmt.Println("before") ws := websocket.Server{} ws.Handshake = hs ws.Handler = echoServer http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("./static")))) http.Handle("/websockets/v3", ws) fmt.Println("assigned") err := http.ListenAndServe(":8080", nil) if err != nil { panic("ListenAndServe: " + err.Error()) } }
// WebSocket adds a WebSocket route > handler to the router. func (e *Echo) WebSocket(path string, h HandlerFunc) { e.Get(path, func(c *Context) (err error) { wss := websocket.Server{ Handler: func(ws *websocket.Conn) { c.socket = ws c.response.status = http.StatusSwitchingProtocols err = h(c) }, } wss.ServeHTTP(c.response, c.request) return err }) }
func main() { seed := time.Now().UTC().UnixNano() rand.Seed(seed) Config = load("config.json") //http.Handle("/", websocket.Handler(wsHandler)) http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{Handler: websocket.Handler(wsHandler)} s.ServeHTTP(w, req) }) delay, _ := time.ParseDuration(Config.Delay) interval, _ := time.ParseDuration(Config.Interval) timer := time.NewTimer(delay) if !Config.OnlyTestConnect { go func() { for { <-timer.C timer.Reset(interval) totalLen := 0 for i := 0; i < n; i++ { totalLen += wsList[i].Len() } if totalLen >= Config.TotalSize { fmt.Println("send timestamp to all") for i := 0; i < n; i++ { for e := wsList[i].Front(); e != nil; e = e.Next() { var ws = e.Value.(*websocket.Conn) now := time.Now().UnixNano() / int64(time.Millisecond) err := websocket.Message.Send(ws, strconv.FormatInt(now, 10)) if err != nil { panic("Error: " + err.Error()) } } } } else { fmt.Println("current websockets: " + strconv.Itoa(totalLen)) } } }() } err := http.ListenAndServe(":"+strconv.Itoa(Config.Port), nil) if err != nil { panic("Error: " + err.Error()) } }
func (srv *Server) apiHandler(w http.ResponseWriter, req *http.Request) { reqNotifier := newRequestNotifier(&srv.connections) reqNotifier.join(req) defer reqNotifier.leave() wsServer := websocket.Server{ Handler: func(conn *websocket.Conn) { modelUUID := req.URL.Query().Get(":modeluuid") logger.Tracef("got a request for model %q", modelUUID) if err := srv.serveConn(conn, reqNotifier, modelUUID); err != nil { logger.Errorf("error serving RPCs: %v", err) } }, } wsServer.ServeHTTP(w, req) }
func managementInterface() { http.Handle("/", http.FileServer(http.Dir("/var/www"))) http.HandleFunc("/control", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{ Handler: websocket.Handler(handleManagementConnection)} s.ServeHTTP(w, req) }) err := http.ListenAndServe(managementAddr, nil) if err != nil { log.Printf("managementInterface ListenAndServe: %s\n", err.Error()) } }
func (h *handler) sendContinuousChangesByWebSocket(inChannels base.Set, options db.ChangesOptions) error { handler := func(conn *websocket.Conn) { h.logStatus(101, "Upgraded to WebSocket protocol") defer func() { conn.Close() base.LogTo("HTTP+", "#%03d: --> WebSocket closed", h.serialNumber) }() // Read changes-feed options from an initial incoming WebSocket message in JSON format: if msg, err := readWebSocketMessage(conn); err != nil { return } else { var channelNames []string var err error if _, options, _, channelNames, err = h.readChangesOptionsFromJSON(msg); err != nil { return } if channelNames != nil { inChannels, _ = channels.SetFromArray(channelNames, channels.ExpandStar) } } options.Terminator = make(chan bool) defer close(options.Terminator) caughtUp := false h.generateContinuousChanges(inChannels, options, func(changes []*db.ChangeEntry) error { var data []byte if changes != nil { data, _ = json.Marshal(changes) } else if !caughtUp { caughtUp = true data, _ = json.Marshal([]*db.ChangeEntry{}) } else { data = []byte{} } _, err := conn.Write(data) return err }) } server := websocket.Server{ Handshake: func(*websocket.Config, *http.Request) error { return nil }, Handler: handler, } server.ServeHTTP(h.response, h.rq) return nil }
func run() { glog.Info("run()") http.Handle(indexPath, http.FileServer(http.Dir("client"))) http.HandleFunc(wsPath, func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{Handler: websocket.Handler(handler)} s.ServeHTTP(w, req) }) err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil) if err != nil { glog.Error(err) exitStatus = 1 } }
// ServeHTTP implements the http.Handler interface. func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { server := websocket.Server{ Handler: func(socket *websocket.Conn) { defer socket.Close() st, entity, err := h.ctxt.stateForRequestAuthenticatedAgent(req) if err != nil { h.sendError(socket, req, err) return } tag := entity.Tag() // If we get to here, no more errors to report, so we report a nil // error. This way the first line of the socket is always a json // formatted simple error. h.sendError(socket, req, nil) filePrefix := st.EnvironUUID() + " " + tag.String() + ":" dbLogger := state.NewDbLogger(st, tag) defer dbLogger.Close() m := new(params.LogRecord) for { if err := websocket.JSON.Receive(socket, m); err != nil { if err != io.EOF { logger.Errorf("error while receiving logs: %v", err) } break } fileErr := h.logToFile(filePrefix, m) if fileErr != nil { logger.Errorf("logging to logsink.log failed: %v", fileErr) } dbErr := dbLogger.Log(m.Time, m.Module, m.Location, m.Level, m.Message) if dbErr != nil { logger.Errorf("logging to DB failed: %v", err) } if fileErr != nil || dbErr != nil { break } } }} server.ServeHTTP(w, req) }
// WebSocket adds a websocket route func (g *routeGroup) WebSocket(path string, h Handler) { handler := g.lars.wrapHandler(h) g.Get(path, func(c Context) { ctx := c.BaseContext() wss := websocket.Server{ Handler: func(ws *websocket.Conn) { ctx.websocket = ws ctx.response.status = http.StatusSwitchingProtocols ctx.Next() }, } wss.ServeHTTP(ctx.response, ctx.request) }, handler) }
// ServeHTTP implements the http.Handler interface. func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { server := websocket.Server{ Handler: func(socket *websocket.Conn) { defer socket.Close() st, entity, err := h.ctxt.stateForRequestAuthenticatedAgent(req) if err != nil { h.sendError(socket, req, err) return } tag := entity.Tag() filePrefix := st.ModelUUID() + " " + tag.String() + ":" dbLogger := state.NewDbLogger(st, tag) defer dbLogger.Close() // If we get to here, no more errors to report, so we report a nil // error. This way the first line of the socket is always a json // formatted simple error. h.sendError(socket, req, nil) logCh := h.receiveLogs(socket) for { select { case <-h.ctxt.stop(): return case m := <-logCh: fileErr := h.logToFile(filePrefix, m) if fileErr != nil { logger.Errorf("logging to logsink.log failed: %v", fileErr) } dbErr := dbLogger.Log(m.Time, m.Module, m.Location, m.Level, m.Message) if dbErr != nil { logger.Errorf("logging to DB failed: %v", err) } if fileErr != nil || dbErr != nil { return } } } }, } server.ServeHTTP(w, req) }
func main() { seed := time.Now().UTC().UnixNano() rand.Seed(seed) Config = load("config.json") fmt.Print("123") http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{Handler: websocket.Handler(wsHandler)} s.ServeHTTP(w, req) }) err := http.ListenAndServe(":"+strconv.Itoa(Config.Port), nil) if err != nil { panic("Error: " + err.Error()) } }
func managementInterface() { http.Handle("/", http.FileServer(http.Dir("/var/www"))) http.Handle("/logs/", http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log")))) http.HandleFunc("/control", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{ Handler: websocket.Handler(handleManagementConnection)} s.ServeHTTP(w, req) }) http.HandleFunc("/getTraffic", handleTrafficRequest) http.HandleFunc("/getSituation", handleSituationRequest) http.HandleFunc("/getTowers", handleTowersRequest) err := http.ListenAndServe(managementAddr, nil) if err != nil { log.Printf("managementInterface ListenAndServe: %s\n", err.Error()) } }
func (s *containerRouter) wsContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } containerName := vars["name"] if !s.backend.Exists(containerName) { return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) } var keys []byte var err error detachKeys := r.FormValue("detachKeys") if detachKeys != "" { keys, err = term.ToBytes(detachKeys) if err != nil { logrus.Warnf("Invalid escape keys provided (%s) using default : ctrl-p ctrl-q", detachKeys) } } h := websocket.Handler(func(ws *websocket.Conn) { defer ws.Close() wsAttachWithLogsConfig := &daemon.ContainerWsAttachWithLogsConfig{ InStream: ws, OutStream: ws, ErrStream: ws, Logs: httputils.BoolValue(r, "logs"), Stream: httputils.BoolValue(r, "stream"), DetachKeys: keys, } if err := s.backend.ContainerWsAttachWithLogs(containerName, wsAttachWithLogsConfig); err != nil { logrus.Errorf("Error attaching websocket: %s", utils.GetErrorMessage(err)) } }) ws := websocket.Server{Handler: h, Handshake: nil} ws.ServeHTTP(w, r) return nil }
func (this *App) safeRun(w http.ResponseWriter, r *http.Request) (httpStatus int) { defer func() { if err := recover(); err != nil { msg := fmt.Sprintln(r.URL.Path, err, ";trace", string(debug.Stack())) this.appLogger.Error(msg) httpStatus = http.StatusInternalServerError } }() controller := this.Router.GetController(r.URL.Path) defer context.Clear(r) if controller != nil { controller.Init(w, r) controller.SetLogger(this.getControllerLogger(controller.GetControllerName())) controller.SetCache(this.cache) controller.SetOrm(this.orm) preloadErr := controller.Preload() if preloadErr == nil { switch controller.GetConnectMode() { case HttpMode: ControllerHandleFunc(controller, r.Method, r.URL.Path) //campatible websocket case WebsocketMode: webHandler := func(conn *websocket.Conn) { controller.SetWebsocketConnection(conn) controller.Get() } s := websocket.Server{Handler: webHandler} s.ServeHTTP(w, r) } } controller.Flush() httpStatus = http.StatusOK } else { httpStatus = http.StatusNotFound w.WriteHeader(http.StatusNotFound) } return }
func pubsocketdHandler(w http.ResponseWriter, req *http.Request) { // See above (20140729/straup) if websocketAllowInsecure { s := websocket.Server{ Handler: websocket.Handler(pubSubHandler), } s.ServeHTTP(w, req) } else { originURL := websocketAllowableURLs[0] pubsocketdConfig := websocket.Config{Origin: &originURL} s := websocket.Server{ Config: pubsocketdConfig, Handshake: pubsocketdHandshake, Handler: websocket.Handler(pubSubHandler), } s.ServeHTTP(w, req) } }
func (w *WebServer) start(host string) { http.HandleFunc("/ws-server", func(w http.ResponseWriter, req *http.Request) { s := websocket.Server{ Handler: websocket.Handler(func(ws *websocket.Conn) { jsonrpc.ServeConn(ws) }), } s.ServeHTTP(w, req) log.Println("connected ws-server") }) http.HandleFunc("/ws-client", func(rw http.ResponseWriter, req *http.Request) { s := websocket.Server{ Handler: websocket.Handler(func(ws *websocket.Conn) { w.client = jsonrpc.NewClient(ws) w.ch <- struct{}{} <-w.ch }), } s.ServeHTTP(rw, req) log.Println("connected ws-client") }) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, r.URL.Path[1:]) }) if err := http.ListenAndServe(host, nil); err != nil { log.Fatal(err) } }