mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-03-02 18:10:20 +00:00
- add swagger definitions for all API routes - self-host the swagger UI on `/swagger/` - serve swagger spec on `/swagger.json`
91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var wsCon = websocket.Upgrader{}
|
|
|
|
// EchoWS godoc
|
|
// @Summary Echo over websockets
|
|
// @Description echos content via websockets
|
|
// @Tags HTTP API
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Router /ws/echo [post]
|
|
// @Success 202 {object} api.MapResponse
|
|
// Test: go run ./cmd/podcli/* ws localhost:9898/ws/echo
|
|
func (s *Server) echoWsHandler(w http.ResponseWriter, r *http.Request) {
|
|
c, err := wsCon.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
if err != nil {
|
|
s.logger.Warn("websocket upgrade error", zap.Error(err))
|
|
return
|
|
}
|
|
}
|
|
defer c.Close()
|
|
done := make(chan struct{})
|
|
defer close(done)
|
|
in := make(chan interface{})
|
|
defer close(in)
|
|
go s.writeWs(c, in)
|
|
go s.sendHostWs(c, in, done)
|
|
for {
|
|
_, message, err := c.ReadMessage()
|
|
if err != nil {
|
|
if !strings.Contains(err.Error(), "close") {
|
|
s.logger.Warn("websocket read error", zap.Error(err))
|
|
}
|
|
break
|
|
}
|
|
var response = struct {
|
|
Time time.Time `json:"ts"`
|
|
Message string `json:"msg"`
|
|
}{
|
|
Time: time.Now(),
|
|
Message: string(message),
|
|
}
|
|
in <- response
|
|
}
|
|
}
|
|
|
|
func (s *Server) sendHostWs(ws *websocket.Conn, in chan interface{}, done chan struct{}) {
|
|
ticker := time.NewTicker(5 * time.Second)
|
|
defer ticker.Stop()
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
var status = struct {
|
|
Time time.Time `json:"ts"`
|
|
Host string `json:"server"`
|
|
}{
|
|
Time: time.Now(),
|
|
Host: s.config.Hostname,
|
|
}
|
|
in <- status
|
|
case <-done:
|
|
s.logger.Debug("websocket exit")
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Server) writeWs(ws *websocket.Conn, in chan interface{}) {
|
|
for {
|
|
select {
|
|
case msg := <-in:
|
|
if err := ws.WriteJSON(msg); err != nil {
|
|
if !strings.Contains(err.Error(), "close") {
|
|
s.logger.Warn("websocket write error", zap.Error(err))
|
|
}
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|