Skip to content

Instantly share code, notes, and snippets.

@ismiyati
Last active March 22, 2019 03:28
Show Gist options
  • Select an option

  • Save ismiyati/79d7fd94a8ba5b74c10556f461c1fcfb to your computer and use it in GitHub Desktop.

Select an option

Save ismiyati/79d7fd94a8ba5b74c10556f461c1fcfb to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net"
"net/http"
"sync"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
)
var wsClientHtm = []byte(`
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="connect-src * 'unsafe-inline';">
<script src="/wsclient.js"></script>
<style>
table { border: 2px solid black; }
input { width: 300px; }
select { width: 300px; }
textarea { width: 513px; border: 2px solid black; }
#btnConnect { width: 100px; }
#btnDisconnect { width: 100px; }
#btnSend { width: 100px; }
</style>
</head>
<body>
<h1>WebSocket Client</h1>
<!-- WebSocket Connection Parameters Table -->
<table>
<tr>
<td width="200px">WS Protocol</td>
<td>
<select id="protocol">
<option value="ws" selected="selected">ws</option>
<option value="wss">wss</option>
</select>
</td>
</tr>
<tr>
<td>WS Hostname</td>
<td><input type="text" id="hostname" value="localhost"/></td>
</tr>
<tr>
<td>WS Port</td>
<td><input type="text" id="port" value="8080"/></td>
</tr>
<tr>
<td>WS Endpoint</td>
<td><input type="text" id="endpoint" value="/wsserver"/></td>
</tr>
<tr>
<td></td>
<td>
<input id="btnConnect" type="button" value="Connect" onclick="onConnectClick()">&nbsp;&nbsp;
<input id="btnDisconnect" type="button" value="Disconnect" onclick="onDisconnectClick()" disabled="disabled">
</td>
</tr>
</table><br/>
<!-- Send Message Table -->
<table>
<tr>
<td width="200px">Message</td>
<td><input type="text" id="message"/></td>
</tr>
<tr>
<td></td>
<td>
<input id="btnSend" type="button" value="Send Message" disabled="disabled" onclick="onSendClick()">
</td>
</tr>
</table><br/>
<textarea id="incomingMsgOutput" rows="10" cols="20" disabled="disabled"></textarea>
</body>
</html>
`)
var wsClientJs = []byte(`
var webSocket = null;
var ws_protocol = null;
var ws_hostname = null;
var ws_port = null;
var ws_endpoint = null;
/**
* Event handler for clicking on button "Connect"
*/
function onConnectClick() {
var ws_protocol = document.getElementById("protocol").value;
var ws_hostname = document.getElementById("hostname").value;
var ws_port = document.getElementById("port").value;
var ws_endpoint = document.getElementById("endpoint").value;
openWSConnection(ws_protocol, ws_hostname, ws_port, ws_endpoint);
}
/**
* Event handler for clicking on button "Disconnect"
*/
function onDisconnectClick() {
webSocket.close();
}
/**
* Open a new WebSocket connection using the given parameters
*/
function openWSConnection(protocol, hostname, port, endpoint) {
var webSocketURL = null;
webSocketURL = protocol + "://" + hostname + ":" + port + endpoint;
console.log("openWSConnection::Connecting to: " + webSocketURL);
try {
webSocket = new WebSocket(webSocketURL);
webSocket.onopen = function(openEvent) {
console.log("WebSocket OPEN: " + JSON.stringify(openEvent, null, 4));
document.getElementById("btnSend").disabled = false;
document.getElementById("btnConnect").disabled = true;
document.getElementById("btnDisconnect").disabled = false;
};
webSocket.onclose = function (closeEvent) {
console.log("WebSocket CLOSE: " + JSON.stringify(closeEvent, null, 4));
document.getElementById("btnSend").disabled = true;
document.getElementById("btnConnect").disabled = false;
document.getElementById("btnDisconnect").disabled = true;
};
webSocket.onerror = function (errorEvent) {
console.log("WebSocket ERROR: " + JSON.stringify(errorEvent, null, 4));
};
webSocket.onmessage = function (messageEvent) {
var wsMsg = messageEvent.data;
console.log("WebSocket MESSAGE: " + wsMsg);
if (wsMsg.indexOf("error") > 0) {
document.getElementById("incomingMsgOutput").value += "error: " + wsMsg.error + "\r\n";
} else {
document.getElementById("incomingMsgOutput").value += "message: " + wsMsg + "\r\n";
}
};
} catch (exception) {
console.error(exception);
}
}
/**
* Send a message to the WebSocket server
*/
function onSendClick() {
if (webSocket.readyState != WebSocket.OPEN) {
console.error("webSocket is not open: " + webSocket.readyState);
return;
}
var msg = document.getElementById("message").value;
webSocket.send(msg);
}
`)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write(wsClientHtm)
})
http.HandleFunc("/wsclient.js", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write(wsClientJs)
})
mu := &sync.Mutex{}
conns := map[net.Conn]ws.OpCode{}
http.HandleFunc("/wsserver", func(w http.ResponseWriter, r *http.Request) {
conn, _, _, err := ws.UpgradeHTTP(r, w)
if err != nil {
// handle error
fmt.Println("err1:", err)
return
}
go func() {
defer func() {
mu.Lock()
delete(conns, conn)
mu.Unlock()
conn.Close()
}()
for {
msg, op, err := wsutil.ReadClientData(conn)
if err != nil {
// handle error
fmt.Println("err2:", err)
return
}
mu.Lock()
conns[conn] = op
mu.Unlock()
for conn, op := range conns {
err = wsutil.WriteServerMessage(conn, op, msg)
if err != nil {
// handle error
fmt.Println("err3", err)
return
}
}
}
}()
})
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment