Server.go
package main
import (
"fmt"
"golang.org/x/net/websocket"
"html/template"
"io"
"log"
"net/http"
"time"
)
var (
msgCh chan string
conns map[*websocket.Conn]string
Names = []string{"Ulmer","zoe","Charlotte","Dylan","Edward","Freya",
"Gale","Mollie","Andrew","Charlotte","Elsa"}
msgCache = []string{}
CacheLen = 20
)
func main() {
msgCh = make(chan string, 1)
conns = make(map[*websocket.Conn]string)
http.HandleFunc("/", homeHandler)
//http.HandleFunc("/ws", wsHandler)
http.Handle("/ws", websocket.Handler(wsHandler))
go writer()
log.Fatal(http.ListenAndServe(":9999", nil))
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
tmp, err := template.ParseFiles("./client.html")
if err != nil {
log.Fatal(err)
}
err = tmp.ExecuteTemplate(w, "home", r.Host)
if err != nil {
log.Fatal(err)
}
}
func wsHandler(ws *websocket.Conn) {
if _, ok := conns[ws]; !ok {
conns[ws] = Names[0]
Names = Names[1:]
}
for i:=0;i<len(msgCache);i++ {
_, err := ws.Write([]byte(msgCache[i]))
if err != nil {
fmt.Println(conns[ws]+" closed")
ws.Close()
delete(conns, ws)
}
}
reader(ws)
}
func reader(ws *websocket.Conn) {
buf := make([]byte, 1024)
for {
n, err := ws.Read(buf)
if err != nil {
if err == io.EOF {
continue
}
break
}
timeStr := time.Now().Format("2006-01-02 15:04:05")
msg := conns[ws]+"("+timeStr[5:]+")"+" : "+string(buf[:n])
msgCh <- msg
if len(msgCache)<CacheLen {
msgCache = append(msgCache, msg)
}else {
msgCache = append(msgCache[1:], msg)
}
}
fmt.Println(conns[ws]+" closed")
ws.Close()
delete(conns, ws)
}
func writer() {
for {
message := <-msgCh
for ws, _ := range conns {
_, err := ws.Write([]byte(message))
if err != nil {
fmt.Println(conns[ws]+" closed")
ws.Close()
delete(conns, ws)
}
}
}
}
client.html
{{define "home"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="log"></div>
<form id="form">
<input type="submit" value="Send"/>
<input type="text" id="msg" size="64"/>
</form>
</body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(function () {
var conn;
var msg = $("#msg");
var log = $("#log");
function appendLog(msg) {
var d = log[0]
var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
msg.appendTo(log)
if (doScroll) {
d.scrollTop = d.scrollHeight - d.clientHeight;
}
}
$("#form").submit(function () {
if (!conn) {
return false;
}
if (!msg.val()) {
return false;
}
conn.send(msg.val());
msg.val("");
return false
});
if (window["WebSocket"]) {
conn = new WebSocket("ws://{{$}}/ws");
appendLog($("<div/>").text("welcome to our chatRoom"))
conn.onclose = function (evt) {
appendLog($("<div><b>Connection closed.</b></div>"))
}
conn.onmessage = function (evt) {
appendLog($("<div/>").text(evt.data))
}
} else {
appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
}
});
</script>
<style type="text/css">
html {
overflow: hidden;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background: gray;
}
#log {
background: white;
margin: 0;
padding: 0.5em 0.5em 0.5em 0.5em;
position: absolute;
top: 0.5em;
left: 0.5em;
right: 0.5em;
bottom: 3em;
overflow: auto;
}
#form {
padding: 0 0.5em 0 0.5em;
margin: 0;
position: absolute;
bottom: 1em;
left: 0px;
width: 100%;
overflow: hidden;
}
</style>
</html>
{{end}}