basic htmx with server sending content to the client over a websocket is now working. This only worked when text message where being sent so the websocket handling had to be made configurable with a 'text' boolean field.
This commit is contained in:
parent
77cffde408
commit
39cf088a41
@ -258,7 +258,7 @@ func main() {
|
||||
log.Println("WebSocket connection error:", err)
|
||||
return
|
||||
}
|
||||
wsConn := websocketutil.NewWebSocketConn(conn)
|
||||
wsConn := websocketutil.NewWebSocketConn(conn, false)
|
||||
defer wsConn.Close()
|
||||
|
||||
serverInfo, err := comms.AgentInitialization(wsConn, comms.NewAgentInfo())
|
||||
|
@ -9,12 +9,11 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
_ "net/http/pprof"
|
||||
)
|
||||
|
||||
func parsePublicId(path string) (publicId string, _ error) {
|
||||
@ -97,6 +96,8 @@ func main() {
|
||||
log.Printf("Using username '%s' and password '%s'", userPassword.Username, userPassword.Password)
|
||||
|
||||
admin := converge.NewAdmin()
|
||||
|
||||
// For agents connecting
|
||||
registrationService := websocketutil.WebSocketService{
|
||||
Handler: func(w http.ResponseWriter, r *http.Request, conn net.Conn) {
|
||||
publicId, err := parsePublicId(r.URL.Path)
|
||||
@ -112,6 +113,8 @@ func main() {
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// For users connecting with ssh
|
||||
clientService := websocketutil.WebSocketService{
|
||||
Handler: func(w http.ResponseWriter, r *http.Request, conn net.Conn) {
|
||||
publicId, err := parsePublicId(r.URL.Path)
|
||||
@ -127,9 +130,16 @@ func main() {
|
||||
},
|
||||
}
|
||||
|
||||
// for the web browser getting live status updates.
|
||||
sessionService := websocketutil.WebSocketService{
|
||||
Handler: sessionHandler,
|
||||
Text: true,
|
||||
}
|
||||
|
||||
// websocket endpoints
|
||||
http.HandleFunc("/agent/", registrationService.Handle)
|
||||
http.HandleFunc("/client/", clientService.Handle)
|
||||
http.HandleFunc("/ws/sessions", sessionService.Handle)
|
||||
|
||||
// create filehandler with templating for html files.
|
||||
http.Handle("/docs/", http.StripPrefix("/docs/", http.HandlerFunc(pageHandler)))
|
||||
|
@ -32,7 +32,7 @@ func pageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
case "index.html":
|
||||
templates.AboutTab().Render(r.Context(), w)
|
||||
case "usage.html":
|
||||
templates.UsageTab(secure, r.URL.Host, username).Render(r.Context(), w)
|
||||
templates.UsageTab(secure, r.Host, username).Render(r.Context(), w)
|
||||
case "downloads.html":
|
||||
templates.DownloadsTab().Render(r.Context(), w)
|
||||
case "sessions.html":
|
||||
|
55
cmd/converge/sessionhandler.go
Normal file
55
cmd/converge/sessionhandler.go
Normal file
@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
func sessionHandler(w http.ResponseWriter, r *http.Request, conn net.Conn) {
|
||||
log.Println("Got sessions websocket connection")
|
||||
i := 0
|
||||
for {
|
||||
time.Sleep(1 * time.Second)
|
||||
message := Message{
|
||||
Type: "update",
|
||||
Content: `
|
||||
<div id="mycontent">
|
||||
New data: ` + strconv.Itoa(i) + `
|
||||
</div>
|
||||
`,
|
||||
}
|
||||
_, err := json.Marshal(message)
|
||||
if err != nil {
|
||||
log.Printf("ERROR marshalling json: %v", err)
|
||||
return
|
||||
}
|
||||
//conn.Write(data)
|
||||
go func() {
|
||||
for {
|
||||
b := make([]byte, 1024)
|
||||
_, err := conn.Read(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
_, err = conn.Write([]byte(message.Content))
|
||||
if err == nil {
|
||||
_, err = conn.Write([]byte("\n"))
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("ERROR sending message: %v", err)
|
||||
return
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ func handleConnection(conn net.Conn, wsURL string, insecure bool) {
|
||||
log.Println("WebSocket connection error:", err)
|
||||
return
|
||||
}
|
||||
wsConn := websocketutil.NewWebSocketConn(_wsConn)
|
||||
wsConn := websocketutil.NewWebSocketConn(_wsConn, false)
|
||||
defer wsConn.Close()
|
||||
|
||||
iowrappers.SynchronizeStreams(wsConn, conn)
|
||||
|
@ -70,7 +70,7 @@ func main() {
|
||||
log.Println("WebSocket connection error:", err)
|
||||
panic(err)
|
||||
}
|
||||
wsConn := websocketutil.NewWebSocketConn(_wsConn)
|
||||
wsConn := websocketutil.NewWebSocketConn(_wsConn, false)
|
||||
defer wsConn.Close()
|
||||
|
||||
iowrappers.SynchronizeStreams(wsConn, Stdio{})
|
||||
|
@ -35,7 +35,7 @@ func main() {
|
||||
|
||||
func handleWebSocket(w http.ResponseWriter, r *http.Request, tcpConn net.Conn) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
wsConn := websocketutil.NewWebSocketConn(conn)
|
||||
wsConn := websocketutil.NewWebSocketConn(conn, false)
|
||||
if err != nil {
|
||||
log.Println("Error upgrading to WebSocket:", err)
|
||||
return
|
||||
|
@ -7,3 +7,6 @@ services:
|
||||
context: .
|
||||
ports:
|
||||
- 8000:8000
|
||||
environment:
|
||||
CONVERGE_USERNAME: abc
|
||||
CONVERGE_PASSWORD: "123"
|
||||
|
@ -17,9 +17,17 @@ templ BasePage(tab int) {
|
||||
<link rel="stylesheet" href="../static/css/bootstrap.min.css"
|
||||
crossorigin="anonymous">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<script src="../static/js/htmx.1.9.12.js"></script>
|
||||
<script src="../static/js/htmx.ws.1.9.12.js"></script>
|
||||
|
||||
<title>Converge</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
htmx.logAll();
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../static/js/bootstrap.bundle.min.js"
|
||||
crossorigin="anonymous"></script>
|
||||
|
@ -2,9 +2,12 @@ package templates
|
||||
|
||||
|
||||
templ Sessions() {
|
||||
<div>
|
||||
To be done
|
||||
<div hx-ext="ws" ws-connect="ws://localhost:8000/ws/sessions">
|
||||
<div id="mycontent">
|
||||
Initial content
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,12 +12,12 @@ templ Usage(secure string, host string, username string) {
|
||||
</p>
|
||||
<pre>{`
|
||||
# linux
|
||||
`}curl http{secure}://{host}/docs/agent > agent{`
|
||||
`}curl http{secure}://{host}/static/agent > agent{`
|
||||
chmod 755 agent
|
||||
`}./agent --id ID ws{secure}://{host}{`
|
||||
|
||||
# windows
|
||||
`}curl http{secure}://{host}/docs/agent.exe > agent.exe{`
|
||||
`}curl http{secure}://{host}/static/agent.exe > agent.exe{`
|
||||
`}agent --id ID ws{secure}://{host}{`
|
||||
`}</pre>
|
||||
<p>
|
||||
|
@ -9,6 +9,11 @@ import (
|
||||
type WebSocketConn struct {
|
||||
conn *websocket.Conn
|
||||
buf []byte
|
||||
text bool
|
||||
}
|
||||
|
||||
func NewWebSocketConn(conn *websocket.Conn, text bool) *WebSocketConn {
|
||||
return &WebSocketConn{conn: conn, text: text}
|
||||
}
|
||||
|
||||
func (websocketConn *WebSocketConn) Read(p []byte) (n int, err error) {
|
||||
@ -26,12 +31,12 @@ func (websocketConn *WebSocketConn) Read(p []byte) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
func NewWebSocketConn(conn *websocket.Conn) *WebSocketConn {
|
||||
return &WebSocketConn{conn: conn}
|
||||
}
|
||||
|
||||
func (websocketConn *WebSocketConn) Write(p []byte) (n int, err error) {
|
||||
err = websocketConn.conn.WriteMessage(websocket.BinaryMessage, p)
|
||||
messageType := websocket.BinaryMessage
|
||||
if websocketConn.text {
|
||||
messageType = websocket.TextMessage
|
||||
}
|
||||
err = websocketConn.conn.WriteMessage(messageType, p)
|
||||
if err == nil {
|
||||
n = len(p)
|
||||
}
|
||||
@ -73,5 +78,5 @@ func ConnectWebSocket(conn net.Conn, urlStr string) (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWebSocketConn(wsConn), nil
|
||||
return NewWebSocketConn(wsConn, false), nil
|
||||
}
|
||||
|
@ -22,13 +22,14 @@ var upgrader = websocket.Upgrader{
|
||||
}
|
||||
|
||||
func handleWebSocket(w http.ResponseWriter, r *http.Request,
|
||||
handler func(w http.ResponseWriter, r *http.Request, websockerConnection net.Conn)) {
|
||||
handler func(w http.ResponseWriter, r *http.Request, websockerConnection net.Conn),
|
||||
text bool) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Println("Error upgrading to WebSocket:", err)
|
||||
return
|
||||
}
|
||||
wsConn := NewWebSocketConn(conn)
|
||||
wsConn := NewWebSocketConn(conn, text)
|
||||
defer wsConn.Close()
|
||||
|
||||
handler(w, r, wsConn)
|
||||
@ -36,8 +37,9 @@ func handleWebSocket(w http.ResponseWriter, r *http.Request,
|
||||
|
||||
type WebSocketService struct {
|
||||
Handler func(w http.ResponseWriter, r *http.Request, conn net.Conn)
|
||||
Text bool
|
||||
}
|
||||
|
||||
func (endpoint *WebSocketService) Handle(w http.ResponseWriter, r *http.Request) {
|
||||
handleWebSocket(w, r, endpoint.Handler)
|
||||
handleWebSocket(w, r, endpoint.Handler, endpoint.Text)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user