mirror of https://github.com/gorilla/websocket.git
Add pinging to command example
This commit is contained in:
parent
7f59b56ea4
commit
d14d8b4715
|
@ -30,11 +30,19 @@ const (
|
||||||
|
|
||||||
// Maximum message size allowed from peer.
|
// Maximum message size allowed from peer.
|
||||||
maxMessageSize = 8192
|
maxMessageSize = 8192
|
||||||
|
|
||||||
|
// Time allowed to read the next pong message from the peer.
|
||||||
|
pongWait = 60 * time.Second
|
||||||
|
|
||||||
|
// Send pings to peer with this period. Must be less than pongWait.
|
||||||
|
pingPeriod = (pongWait * 9) / 10
|
||||||
)
|
)
|
||||||
|
|
||||||
func pumpStdin(ws *websocket.Conn, w io.Writer) {
|
func pumpStdin(ws *websocket.Conn, w io.Writer) {
|
||||||
defer ws.Close()
|
defer ws.Close()
|
||||||
ws.SetReadLimit(maxMessageSize)
|
ws.SetReadLimit(maxMessageSize)
|
||||||
|
ws.SetReadDeadline(time.Now().Add(pongWait))
|
||||||
|
ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
|
||||||
for {
|
for {
|
||||||
_, message, err := ws.ReadMessage()
|
_, message, err := ws.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -45,11 +53,13 @@ func pumpStdin(ws *websocket.Conn, w io.Writer) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Println("exit stdin pump")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
|
func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
|
||||||
defer ws.Close()
|
defer func() {
|
||||||
|
ws.Close()
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
s := bufio.NewScanner(r)
|
s := bufio.NewScanner(r)
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||||
|
@ -60,8 +70,21 @@ func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) {
|
||||||
if s.Err() != nil {
|
if s.Err() != nil {
|
||||||
log.Println("scan:", s.Err())
|
log.Println("scan:", s.Err())
|
||||||
}
|
}
|
||||||
close(done)
|
}
|
||||||
log.Println("exit stdout pump")
|
|
||||||
|
func ping(ws *websocket.Conn, done chan struct{}) {
|
||||||
|
ticker := time.NewTicker(pingPeriod)
|
||||||
|
defer ticker.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
if err := ws.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(writeWait)); err != nil {
|
||||||
|
log.Println("ping:", err)
|
||||||
|
}
|
||||||
|
case <-done:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func internalError(ws *websocket.Conn, msg string, err error) {
|
func internalError(ws *websocket.Conn, msg string, err error) {
|
||||||
|
@ -112,33 +135,33 @@ func serveWs(w http.ResponseWriter, r *http.Request) {
|
||||||
inr.Close()
|
inr.Close()
|
||||||
outw.Close()
|
outw.Close()
|
||||||
|
|
||||||
done := make(chan struct{})
|
stdoutDone := make(chan struct{})
|
||||||
go pumpStdout(ws, outr, done)
|
go pumpStdout(ws, outr, stdoutDone)
|
||||||
|
go ping(ws, stdoutDone)
|
||||||
|
|
||||||
pumpStdin(ws, inw)
|
pumpStdin(ws, inw)
|
||||||
|
|
||||||
// Some commands will exit when stdin is closed.
|
// Some commands will exit when stdin is closed.
|
||||||
inw.Close()
|
inw.Close()
|
||||||
|
|
||||||
// Other comamnds need a bonk on the head.
|
// Other commands need a bonk on the head.
|
||||||
if err := proc.Signal(os.Interrupt); err != nil {
|
if err := proc.Signal(os.Interrupt); err != nil {
|
||||||
log.Println("inter:", err)
|
log.Println("inter:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-stdoutDone:
|
||||||
case <-time.After(time.Second):
|
case <-time.After(time.Second):
|
||||||
// A bigger bonk on the head.
|
// A bigger bonk on the head.
|
||||||
if err := proc.Signal(os.Kill); err != nil {
|
if err := proc.Signal(os.Kill); err != nil {
|
||||||
log.Println("term:", err)
|
log.Println("term:", err)
|
||||||
}
|
}
|
||||||
<-done
|
<-stdoutDone
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := proc.Wait(); err != nil {
|
if _, err := proc.Wait(); err != nil {
|
||||||
log.Println("wait:", err)
|
log.Println("wait:", err)
|
||||||
}
|
}
|
||||||
log.Println("exiting handler")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveHome(w http.ResponseWriter, r *http.Request) {
|
func serveHome(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in New Issue