1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > WebSocket Echo Test Client</ title >
7+ < style >
8+ body {
9+ font-family : Arial, sans-serif;
10+ max-width : 800px ;
11+ margin : 0 auto;
12+ padding : 20px ;
13+ }
14+ .container {
15+ border : 1px solid # ccc ;
16+ border-radius : 8px ;
17+ padding : 20px ;
18+ margin : 10px 0 ;
19+ }
20+ .status {
21+ padding : 10px ;
22+ border-radius : 4px ;
23+ margin : 10px 0 ;
24+ }
25+ .connected { background-color : # d4edda ; color : # 155724 ; }
26+ .disconnected { background-color : # f8d7da ; color : # 721c24 ; }
27+ .connecting { background-color : # fff3cd ; color : # 856404 ; }
28+ # messages {
29+ height : 300px ;
30+ overflow-y : auto;
31+ border : 1px solid # ddd ;
32+ padding : 10px ;
33+ background-color : # f8f9fa ;
34+ font-family : monospace;
35+ white-space : pre-wrap;
36+ }
37+ input [type = "text" ] {
38+ width : 70% ;
39+ padding : 8px ;
40+ margin : 5px ;
41+ }
42+ button {
43+ padding : 8px 16px ;
44+ margin : 5px ;
45+ cursor : pointer;
46+ }
47+ .controls {
48+ margin : 10px 0 ;
49+ }
50+ </ style >
51+ </ head >
52+ < body >
53+ < h1 > 🌊 Hydro WebSocket Echo Test Client</ h1 >
54+
55+ < div class ="container ">
56+ < h3 > Connection</ h3 >
57+ < div >
58+ < label > WebSocket URL:</ label >
59+ < input type ="text " id ="wsUrl " value ="ws://localhost:8080 " placeholder ="ws://localhost:8080 ">
60+ < button onclick ="connect() "> Connect</ button >
61+ < button onclick ="disconnect() "> Disconnect</ button >
62+ </ div >
63+ < div id ="status " class ="status disconnected "> Disconnected</ div >
64+ </ div >
65+
66+ < div class ="container ">
67+ < h3 > Send Messages</ h3 >
68+ < div class ="controls ">
69+ < input type ="text " id ="messageInput " placeholder ="Type your message here... " onkeypress ="handleKeyPress(event) ">
70+ < button onclick ="sendMessage() "> Send Text</ button >
71+ < button onclick ="sendBinary() "> Send Binary</ button >
72+ </ div >
73+ </ div >
74+
75+ < div class ="container ">
76+ < h3 > Messages</ h3 >
77+ < div id ="messages "> </ div >
78+ < button onclick ="clearMessages() "> Clear Messages</ button >
79+ </ div >
80+
81+ < script >
82+ let ws = null ;
83+ let messageCount = 0 ;
84+
85+ function updateStatus ( message , className ) {
86+ const status = document . getElementById ( 'status' ) ;
87+ status . textContent = message ;
88+ status . className = `status ${ className } ` ;
89+ }
90+
91+ function addMessage ( message , type = 'info' ) {
92+ const messages = document . getElementById ( 'messages' ) ;
93+ const timestamp = new Date ( ) . toLocaleTimeString ( ) ;
94+ const prefix = type === 'sent' ? '→ SENT' :
95+ type === 'received' ? '← RECV' :
96+ type === 'error' ? '✗ ERROR' :
97+ type === 'info' ? 'ℹ INFO' : '• ' ;
98+
99+ messages . textContent += `[${ timestamp } ] ${ prefix } : ${ message } \n` ;
100+ messages . scrollTop = messages . scrollHeight ;
101+ }
102+
103+ function connect ( ) {
104+ const url = document . getElementById ( 'wsUrl' ) . value ;
105+
106+ if ( ws && ws . readyState === WebSocket . OPEN ) {
107+ addMessage ( 'Already connected' , 'info' ) ;
108+ return ;
109+ }
110+
111+ updateStatus ( 'Connecting...' , 'connecting' ) ;
112+ addMessage ( `Connecting to ${ url } ` , 'info' ) ;
113+
114+ ws = new WebSocket ( url ) ;
115+
116+ ws . onopen = function ( event ) {
117+ updateStatus ( 'Connected' , 'connected' ) ;
118+ addMessage ( 'WebSocket connection established' , 'info' ) ;
119+ } ;
120+
121+ ws . onmessage = function ( event ) {
122+ messageCount ++ ;
123+ if ( event . data instanceof Blob ) {
124+ // Handle binary data
125+ event . data . text ( ) . then ( text => {
126+ addMessage ( `Binary message: ${ text } ` , 'received' ) ;
127+ } ) ;
128+ } else {
129+ addMessage ( event . data , 'received' ) ;
130+ }
131+ } ;
132+
133+ ws . onclose = function ( event ) {
134+ updateStatus ( 'Disconnected' , 'disconnected' ) ;
135+ addMessage ( `Connection closed (code: ${ event . code } , reason: ${ event . reason } )` , 'info' ) ;
136+ ws = null ;
137+ } ;
138+
139+ ws . onerror = function ( error ) {
140+ updateStatus ( 'Error' , 'disconnected' ) ;
141+ addMessage ( `WebSocket error: ${ error } ` , 'error' ) ;
142+ } ;
143+ }
144+
145+ function disconnect ( ) {
146+ if ( ws ) {
147+ ws . close ( ) ;
148+ addMessage ( 'Disconnecting...' , 'info' ) ;
149+ } else {
150+ addMessage ( 'Not connected' , 'info' ) ;
151+ }
152+ }
153+
154+ function sendMessage ( ) {
155+ const input = document . getElementById ( 'messageInput' ) ;
156+ const message = input . value . trim ( ) ;
157+
158+ if ( ! message ) {
159+ addMessage ( 'Please enter a message' , 'error' ) ;
160+ return ;
161+ }
162+
163+ if ( ! ws || ws . readyState !== WebSocket . OPEN ) {
164+ addMessage ( 'Not connected to WebSocket server' , 'error' ) ;
165+ return ;
166+ }
167+
168+ ws . send ( message ) ;
169+ addMessage ( message , 'sent' ) ;
170+ input . value = '' ;
171+ }
172+
173+ function sendBinary ( ) {
174+ if ( ! ws || ws . readyState !== WebSocket . OPEN ) {
175+ addMessage ( 'Not connected to WebSocket server' , 'error' ) ;
176+ return ;
177+ }
178+
179+ // Send some binary data
180+ const binaryData = new Uint8Array ( [ 72 , 101 , 108 , 108 , 111 , 32 , 66 , 105 , 110 , 97 , 114 , 121 ] ) ; // "Hello Binary"
181+ ws . send ( binaryData ) ;
182+ addMessage ( 'Binary data: [72, 101, 108, 108, 111, 32, 66, 105, 110, 97, 114, 121] ("Hello Binary")' , 'sent' ) ;
183+ }
184+
185+ function clearMessages ( ) {
186+ document . getElementById ( 'messages' ) . textContent = '' ;
187+ messageCount = 0 ;
188+ }
189+
190+ function handleKeyPress ( event ) {
191+ if ( event . key === 'Enter' ) {
192+ sendMessage ( ) ;
193+ }
194+ }
195+
196+ // Auto-connect on page load
197+ window . onload = function ( ) {
198+ addMessage ( 'WebSocket Echo Test Client loaded' , 'info' ) ;
199+ addMessage ( 'Click "Connect" to start testing the Hydro WebSocket server' , 'info' ) ;
200+ } ;
201+ </ script >
202+ </ body >
203+ </ html >
0 commit comments