Basically, user provides a list of files to copy from dest1 to dest2. rsync is fired off by pressing the submitting the button, and I want the realtime output of STDOUT/STDERR display in the same page. I would also be saving this execution as a blob in a MySQL DB. WebSockets?
评论:
AG_Clinton:
dazealex:I did almost exactly that with a python script that ran rsync. I'll show you a very stripped down version of what I have. This is my first time doing something like this and I'm still a beginner, but figured I'd share what worked for me. I used gorilla websockets. I'm sure it could be simplified quite a bit as well.
var ( SyncOutput = make(chan string) SyncClients = make(map[*websocket.Conn]bool) SyncClientsLock = sync.RWMutex{} FileSyncing = false FileSyncLock = sync.RWMutex{} ) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } go WatchOutPutChannel() func runSync() { cmd := exec.Command("python", "-u", config.SyncFilesScript) stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(fmt.Sprintf("Error: %s", err)) } FileSyncLock.Lock() FileSyncing = true FileSyncLock.Unlock() err = cmd.Start() go WatchOutPut(stdout) } func WatchOutPut(out io.Reader) { scanner := bufio.NewScanner(out) for scanner.Scan() { SyncOutput <- scanner.Text() } FileSyncLock.Lock() FileSyncing = false FileSyncLock.Unlock() SyncOutput <- "Sync Finished" } func WatchOutPutChannel() { for { output := <-SyncOutput SyncClientsLock.RLock() for client := range SyncClients { client.WriteMessage(1, []byte(output)) } SyncClientsLock.RUnlock() } } func wsHandlerSync(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println("Failed to set websocket upgrade: %+v", err) return } SyncClientsLock.Lock() SyncClients[conn] = true SyncClientsLock.Unlock() for { _, _, err := conn.ReadMessage() if err != nil { break } } SyncClientsLock.Lock() delete(SyncClients, conn) SyncClientsLock.Unlock() conn.Close() }
toolateforTeddy:Thank you kind sir! Much appreciated.
dazealex:Websockets seems like a good plan.
I like gorilla websockets.
Any examples?
