mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-27 13:01:03 +00:00
WebSocket Test Server
This commit is contained in:
parent
87e332ad1a
commit
6f9c3c2e03
@ -1,10 +1,10 @@
|
||||
# WebSocket - Test Server
|
||||
|
||||
This package implements a bare-bones WebSocket server for testing htmx. It can be used in conjunction with the manual tests in the `/test/manual` directory.
|
||||
This package implements a test-suite WebSocket server for testing htmx.
|
||||
|
||||
## What It Does
|
||||
|
||||
This listens for incoming WebSocket connections coming in to ws://localhost:1323/echo. When it receives messages from any WebSocket client, it responds with that same content in a way that htmx can process. This means, that the response message will look like this: `<div id="idMessage" hx-swap-oob="true">{your message here}</div>`
|
||||
This server listens for incoming WebSocket connections coming in to ws://localhost:1323/echo. When it receives messages from any WebSocket client, it responds with that same content in a way that htmx can process. This means, that the response message will look like this: `<div id="idMessage" hx-swap-oob="true">{your message here}</div>`
|
||||
|
||||
## How to Use This Server
|
||||
|
||||
|
@ -1,35 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func wsHeartbeat(c echo.Context) error {
|
||||
|
||||
handler := websocket.Handler(func(ws *websocket.Conn) {
|
||||
|
||||
defer ws.Close()
|
||||
|
||||
for i := 0; ; i = i + 1 {
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
random := rand.Int()
|
||||
message := `<div id="idMessage" hx-swap-oob="true">Message ` + strconv.Itoa(i) + `: ` + strconv.Itoa(random) + `</div>`
|
||||
|
||||
if err := websocket.Message.Send(ws, message); err != nil {
|
||||
c.Logger().Error("send", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
handler.ServeHTTP(c.Response(), c.Request())
|
||||
return nil
|
||||
}
|
||||
|
||||
func wsEcho(c echo.Context) error {
|
||||
|
||||
handler := websocket.Handler(func(ws *websocket.Conn) {
|
||||
|
||||
defer ws.Close()
|
||||
|
||||
/*
|
||||
var done chan<- bool
|
||||
|
||||
defer func() {
|
||||
close(done)
|
||||
ws.Close()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for i := 0; ; i = i + 1 {
|
||||
time.Sleep(10 * time.Second)
|
||||
if done == nil {
|
||||
return
|
||||
}
|
||||
websocket.Message.Send(ws, "ping #"+strconv.Itoa(i))
|
||||
}
|
||||
}()
|
||||
*/
|
||||
for {
|
||||
|
||||
msg := ""
|
||||
@ -57,9 +67,10 @@ func main() {
|
||||
e.Use(middleware.Logger())
|
||||
e.Use(middleware.Recover())
|
||||
|
||||
e.Static("/", "../static")
|
||||
e.Static("/", "./static")
|
||||
e.Static("/htmx", "../../../src")
|
||||
|
||||
e.GET("/echo", wsEcho)
|
||||
e.Logger.Fatal(e.Start(":1323"))
|
||||
e.GET("/heartbeat", wsHeartbeat)
|
||||
e.Logger.Fatal(e.Start(":80"))
|
||||
}
|
||||
|
64
test/servers/ws/static/index.html
Normal file
64
test/servers/ws/static/index.html
Normal file
@ -0,0 +1,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/stylesheet.css">
|
||||
<title></> htmx WebSocket Server</title>
|
||||
<script src="/htmx/htmx.js"></script>
|
||||
<script src="/htmx/ext/ws.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/hyperscript.org@0.8.3"></script>
|
||||
<script type="text/hyperscript">
|
||||
on click(target) from <#navigation a/>
|
||||
log "got it"
|
||||
take .selected for target
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header"></div>
|
||||
<div id="navigation" hx-target="#page" hx-push-url="false">
|
||||
<a href="index.html" class="selected" hx-boost="false">About</a>
|
||||
<a href="" hx-get="ws-heartbeat.html">Heartbeat Test</a>
|
||||
<a href="" hx-get="ws-echo.html">Echo Test</a>
|
||||
</div>
|
||||
<div id="page">
|
||||
<h1>WebSockets Extension Tests</h1>
|
||||
|
||||
<p>As of version 1.7, WebSocket support has been moved out of the core htmx library and into an extension. This server runs a test suite for the htmx WebSocket extension.</p>
|
||||
<p>This extension connects to a WebSocket echo server and can send and receive messages to and from the server.</p>
|
||||
|
||||
<h3>Required Attributes</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td class="bold nowrap">hx-ext</td>
|
||||
<td>Make sure the SSE extension is initialized on every page or page fragment where you use SSE streams.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bold nowrap">ws-connect</td>
|
||||
<td>Connects to a WebSocket server. Attribute value must begin with ws:// wss://</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bold nowrap">ws-send</td>
|
||||
<td>Add to a form to submit form data to the websocket server instead of to an HTTP server.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Example Code</h3>
|
||||
|
||||
<pre class="code">
|
||||
<body hx-ext="ws">
|
||||
<div ws-connect="wss://my.websocket.server.com"></div>
|
||||
|
||||
<form ws-send>
|
||||
<input name="WebSocketMessage">
|
||||
<form/>
|
||||
</body>
|
||||
</pre>
|
||||
<h3>WebSocket Resources</h3>
|
||||
<ul>
|
||||
<li><a href="https://en.wikipedia.org/wiki/WebSocket">Wikipedia</a></li>
|
||||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API">MDN Web Docs</a></li>
|
||||
<li><a href="https://caniuse.com/eventsource">Can I Use?</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
112
test/servers/ws/static/stylesheet.css
Normal file
112
test/servers/ws/static/stylesheet.css
Normal file
@ -0,0 +1,112 @@
|
||||
*{
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#header {
|
||||
width:100%;
|
||||
height: 100px;
|
||||
background-image:url('white_transparent.svg');
|
||||
background-position:left 50px center;
|
||||
background-repeat:no-repeat;
|
||||
background-size: 300px;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
position:absolute;
|
||||
width:150px;
|
||||
margin-top:50px;
|
||||
margin-left:20px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#navigation > a {
|
||||
display:block;
|
||||
cursor: pointer;
|
||||
text-decoration:none;
|
||||
padding:10px 20px;
|
||||
}
|
||||
|
||||
#navigation > a:hover {
|
||||
background-color:#eee;
|
||||
}
|
||||
|
||||
#navigation > a.selected {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#page {
|
||||
margin: 50px;
|
||||
padding-left:150px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 10px;
|
||||
border: solid 1px gray;
|
||||
margin-bottom: 20px;
|
||||
background-color:#f7f7f7;
|
||||
}
|
||||
|
||||
.container.htmx-settling {
|
||||
border:solid 3px red!important;
|
||||
padding:8px!important;
|
||||
}
|
||||
|
||||
pre.code {
|
||||
font-family:'Courier New', Courier, monospace;
|
||||
background-color: #444440;
|
||||
color: #0f0;
|
||||
padding:30px 5px 30px 15px;
|
||||
overflow-y:scroll;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td {
|
||||
padding:10px 20px;
|
||||
border:solid 1px #ddd;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.demo {
|
||||
padding:10px;
|
||||
margin:20px 0px;
|
||||
color:white;
|
||||
background-color: #999;
|
||||
height:100px;
|
||||
}
|
||||
|
||||
a, a:visited {
|
||||
color:#3465a4;
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
padding:5px 10px;
|
||||
border:none;
|
||||
border-radius:5px;
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
background-color:#3465a4;
|
||||
color:white;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../src/htmx.js"></script>
|
||||
<script src="../../src/ext/ws.js"></script>
|
||||
<title>WebSockets Test</title>
|
||||
</head>
|
||||
|
||||
<body hx-ext="ws" ws-connect="ws://localhost:1323/echo">
|
||||
|
||||
<form ws-send="">
|
||||
<div>Send Message to Echo Server...</div>
|
||||
<div>
|
||||
<input type="text" name="message" style="width:500px;" value="This Is The Message" />
|
||||
<input type="submit"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<br><hr><br>
|
||||
<div id="idMessage"></div>
|
||||
</body>
|
||||
</html>
|
33
test/servers/ws/static/ws-echo.html
Normal file
33
test/servers/ws/static/ws-echo.html
Normal file
@ -0,0 +1,33 @@
|
||||
<h1>Echo Test</h1>
|
||||
<h3>Description</h3>
|
||||
<p>This test lets you send and receive data to and from the WebSocket server. Every message that you send to the server will be "echoed"
|
||||
back to you in a separate message</p>
|
||||
|
||||
<h3>Example HTML</h3>
|
||||
|
||||
<pre class="code">
|
||||
<div hx-ext="ws" ws-connect="ws://localhost/echo">
|
||||
|
||||
<form ws-send>
|
||||
<input type="text" name="message" style="width:500px;" value="This Is The Message" />
|
||||
<input type="submit"/>
|
||||
</form>
|
||||
|
||||
<div id="idMessage"></div>
|
||||
</div>
|
||||
</pre>
|
||||
|
||||
<div class="container" hx-ext="ws" ws-connect="ws://localhost/echo">
|
||||
|
||||
<form ws-send="">
|
||||
<h3>Send a Message</h3>
|
||||
<div>
|
||||
<input type="text" name="message" style="width:500px;" value="This Is The Message" />
|
||||
<input type="submit" value="Send" class="btn primary"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<br>
|
||||
<h3>Receive a Message</h3>
|
||||
<div id="idMessage"></div>
|
||||
</div>
|
17
test/servers/ws/static/ws-heartbeat.html
Normal file
17
test/servers/ws/static/ws-heartbeat.html
Normal file
@ -0,0 +1,17 @@
|
||||
<h1>Heartbeat Test</h1>
|
||||
<h3>Description</h3>
|
||||
<p>This test receives messages from the WebSocket server every second.
|
||||
|
||||
<h3>Example HTML</h3>
|
||||
|
||||
<pre class="code">
|
||||
<div hx-ext="ws" ws-connect="ws://localhost/heartbeat">
|
||||
<div id="idMessage"></div>
|
||||
</div>
|
||||
</pre>
|
||||
|
||||
<div class="container" hx-ext="ws" ws-connect="ws://localhost/heartbeat">
|
||||
<h3>WebSocket Messages</h3>
|
||||
<p>Each message just contains a random number generated by the server</p>
|
||||
<div id="idMessage">Waiting...</div>
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user