Skip to content

Instantly share code, notes, and snippets.

@alashstein
Last active August 13, 2022 08:31
Show Gist options
  • Save alashstein/f8c9eef24055ce2a60e9ecb22b390134 to your computer and use it in GitHub Desktop.
Save alashstein/f8c9eef24055ce2a60e9ecb22b390134 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title> WebSockets </title>
<script>
try {
var sock = new WebSocket("ws://{{.}}/sock");
//sock.binaryType = 'blob'; // can set it to 'blob' or 'arraybuffer
console.log("Websocket - status: " + sock.readyState);
sock.onopen = function (m) {
console.log("CONNECTION opened..." + this.readyState);
}
sock.onmessage = function (m) {
var cb = document.getElementById("chatbox");
cb.value += m.data;
}
sock.onerror = function (m) {
console.log("Error occured sending..." + m.data);
}
sock.onclose = function (m) {
console.log("Disconnected - status " + this.readyState);
}
} catch (exception) {
console.log(exception);
}
</script>
</head>
<body>
<div>
<textarea id="chatbox" readonly rows="10"></textarea>
<br>
<textarea id="textin"></textarea>
<br>
<button class="send" onclick="sendButton()">send</button>
</div>
<script>
var ti = document.getElementById("textin");
// take what's the textbox and send it off
function sendButton(){
sock.send(ti.value);
}
ti.value = ""
</script>
</body>
</html>
package main
import (
"html/template"
"log"
"net/http"
"os"
"golang.org/x/net/websocket"
)
const ( listenAddr = "localhost:8000" )
var (
pwd, _ = os.Getwd()
RootTemp = template.Must(template.ParseFiles(pwd + "/client.html"))
JSON = websocket.JSON // codec for JSON
Message = websocket.Message // codec for string, []byte
ActiveClients = make(map[ClientConn]int) // map containing clients
)
func init() {
http.HandleFunc("/", RootHandler)
http.Handle("/sock", websocket.Handler(SockServer))
}
func main() {
log.Fatal(http.ListenAndServe(listenAddr, nil))
}
// Client connection consists of the websocket and the client ip
type ClientConn struct {
websocket *websocket.Conn
clientIP string
}
func SockServer(ws *websocket.Conn) {
var err error
var clientMessage string
// use []byte if websocket binary type is blob or arraybuffer
// var clientMessage []byte
// cleanup on server side
defer func() {
ws.Close()
}()
client := ws.Request().RemoteAddr
sockCli := ClientConn{ws, client}
ActiveClients[sockCli] = 0
// for loop so the websocket stays open otherwise it'll close after one Receieve and Send
for {
// If cannot Read then the connection is closed
if err = Message.Receive(ws, &clientMessage); err != nil {
// remove the ws client conn from our active clients
delete(ActiveClients, sockCli)
return
}
clientMessage = sockCli.clientIP + " - " + clientMessage + "\n"
for cs, _ := range ActiveClients {
// could not send the message to a peer
Message.Send(cs.websocket, clientMessage)
}
}
}
// RootHandler renders the template for the root page
func RootHandler(w http.ResponseWriter, req *http.Request) {
RootTemp.Execute(w, listenAddr)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment