golang websocket即时聊天室超简版

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}}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值