package ws import ( "context" "fmt" "io" "os" "time" "wssrv/log" "github.com/gorilla/websocket" ) func readMessage(ctx context.Context, cancel context.CancelCauseFunc, con *websocket.Conn) { var ( err error msg []byte ) for err != io.EOF { select { case <-ctx.Done(): return default: if _, msg, err = con.ReadMessage(); err != nil { // chErr <- fmt.Errorf("unable to read from websocket on '%s': %v", con.RemoteAddr(), err) cancel(fmt.Errorf("unable to read from websocket on '%s': %v", con.RemoteAddr(), err)) return } fmt.Printf("(%s): %s\n", con.RemoteAddr(), msg) } } } func sendFile(ctx context.Context, cancel context.CancelCauseFunc, con *websocket.Conn, fileNa string, data []byte, interv time.Duration) { var err error for { select { case <-ctx.Done(): return default: log.Info.Printf("sending file '%s'", fileNa) if err = con.WriteMessage(websocket.TextMessage, data); err != nil { // chErr <- fmt.Errorf("unable write on websocket on '%s': %v", con.RemoteAddr(), err) cancel(fmt.Errorf("unable write on websocket on '%s': %v", con.RemoteAddr(), err)) return } log.Info.Printf("sleeping for '%v'", interv) time.Sleep(interv) } } } func sendFileByInterval(con *websocket.Conn, fileNa string, interv time.Duration) error { var ( err error data []byte ctx, cancel = context.WithCancelCause(context.Background()) ) if data, err = os.ReadFile(fileNa); err != nil { return fmt.Errorf("unable to read file '%s': %v", fileNa, err) } go readMessage(ctx, cancel, con) go sendFile(ctx, cancel, con, fileNa, data, interv) <-ctx.Done() return context.Cause(ctx) } // SendFileByInterval repeatedly sends a given file in the websocket according // to an interval. func SendFileByInterval(con *websocket.Conn, fileNa string, interv time.Duration) error { switch { case con == nil: return fmt.Errorf("nil connection parameter") case len(fileNa) == 0: return fmt.Errorf("empty file parameter") case interv < 1: return fmt.Errorf("non positive interval parameter") } if err := checkFile(fileNa); err != nil { return err } return sendFileByInterval(con, fileNa, interv) }