html5使用go+websocket搭建websocket服务的实例

2020-07-26 22:12:50

这次的就直接发放代码截图吧,应该是用go语言做后台一个简易的聊天,这里没用到什么特别的知识,最朴实的来实现效果,主要目的是分享下h5怎么用websocket,go搭建websocket服务的主要部分。

go代码部分:

// WebChat project main.gopackage mainimport (    "fmt"    "net/http"    "time"    "encoding/json"    "strings"    "golang.org/x/net/websocket")//全局信息var datas Datasvar users map[*websocket.Conn]stringfunc main() {    fmt.Println("启动时间")    fmt.Println(time.Now())    //初始化    datas = Datas{}    users = make(map[*websocket.Conn]string)    //绑定效果页面    http.HandleFunc("/", h_index)    //绑定socket方法    http.Handle("/webSocket", websocket.Handler(h_webSocket))    //开始监听    http.ListenAndServe(":8", nil)}func h_index(w http.ResponseWriter, r *http.Request) {    http.ServeFile(w, r, "index.html")}func h_webSocket(ws *websocket.Conn) {    var userMsg UserMsg    var data string    for {        //判断是否重复连接        if _, ok := users[ws]; !ok {            users[ws] = "匿名"        }        userMsgsLen := len(datas.UserMsgs)        fmt.Println("UserMsgs", userMsgsLen, "users长度:", len(users))        //有消息时,全部分发送数据        if userMsgsLen > 0 {            b, errMarshl := json.Marshal(datas)            if errMarshl != nil {                fmt.Println("全局消息内容异常...")                break            }            for key, _ := range users {                errMarshl = websocket.Message.Send(key, string(b))                if errMarshl != nil {                    //移除出错的链接                    delete(users, key)                    fmt.Println("发送出错...")                    break                }            }            datas.UserMsgs = make([]UserMsg, 0)        }        fmt.Println("开始解析数据...")        err := websocket.Message.Receive(ws, &data)        fmt.Println("data:", data)        if err != nil {            //移除出错的链接            delete(users, ws)            fmt.Println("接收出错...")            break        }        data = strings.Replace(data, "n", "", 0)        err = json.Unmarshal([]byte(data), &userMsg)        if err != nil {            fmt.Println("解析数据异常...")            break        }        fmt.Println("请求数据类型:", userMsg.DataType)        switch userMsg.DataType {        case "send":            //赋值对应的昵称到ws            if _, ok := users[ws]; ok {                users[ws] = userMsg.UserName                //清除连接人昵称信息                datas.UserDatas = make([]UserData, 0)                //重新加载当前在线连接人                for _, item := range users {                    userData := UserData{UserName: item}                    datas.UserDatas = append(datas.UserDatas, userData)                }            }            datas.UserMsgs = append(datas.UserMsgs, userMsg)        }    }}type UserMsg struct {    UserName string    Msg      string    DataType string}type UserData struct {    UserName string}type Datas struct {    UserMsgs  []UserMsg    UserDatas []UserData}

  html代码部分:

<!DOCTYPE html><html><head>    <title></title>    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">    <!-- 新 Bootstrap 核心 CSS 文件 -->    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">    <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>    <!--        <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>--></head><body>    <div>        <div>内容:</div>        <div id="divShow">            <!--<div class="list-group-item list-group-item-success">1111</div>            <div class="list-group-item list-group-item-info">1111</div>            <div class="list-group-item list-group-item-warning">1111</div>            <div class="list-group-item list-group-item-danger">1111</div>-->        </div>        <div id="divUsers">            在线:<br />            <!--<div class="btn btn-default">111</div>-->        </div>        <div>            昵称:<input id="txtUserName" value="红领巾" type="text" maxlength="20" style="width: 30%; margin-bottom: 15px" />            聊聊:<textarea id="txtContent" autofocus rows="6" placeholder="想聊的内容" maxlength="200" required style="width: 60%; "></textarea>            <button class="btn btn-default" id="btnSend" style="margin-top:15px">发 送</button>        </div>    </div></body></html><script>    var tool = function () {        var paperLoopNum = 0;        var paperTempleArr = [            '<div class="list-group-item list-group-item-success">{0}</div>',            '<div class="list-group-item list-group-item-info">{0}</div>',            '<div class="list-group-item list-group-item-warning">{0}</div>',            '<div class="list-group-item list-group-item-danger">{0}</div>'        ];        return {            paperDiv: function (val) {                var hl = paperTempleArr[paperLoopNum];                paperLoopNum++;                if (paperLoopNum >= paperTempleArr.length) { paperLoopNum = 0; }                return this.formart(hl, [val])            },            formart: function (str, arrVal) {                for (var i = 0; i < arrVal.length; i++) {                    str = str.replace("{" + i + "}", arrVal[i]);                }                return str;            }        }    }    function showMsg(id, hl, isAppend) {        if (!isAppend) { $("#" + id).html(hl); } else {            $("#" + id).append(hl);        }    }    $(function () {        //初始化工具方法        var tl = new tool();        var wsUrl = "ws://172.16.9.6:8/webSocket";        ws = new WebSocket(wsUrl);        try {            ws.onopen = function () {                //showMsg("divShow", tl.paperDiv("连接服务器-成功"));            }            ws.onclose = function () {                if (ws) {                    ws.close();                    ws = null;                }                showMsg("divShow", tl.paperDiv("连接服务器-关闭"), true);            }            ws.onmessage = function (result) {                //console.log(result.data);                var data = JSON.parse(result.data);                $(data.UserMsgs).each(function (i, item) {                    showMsg("divShow", tl.paperDiv("【" + item.UserName + "】:" + item.Msg), true);                });                var userDataShow = [];                $(data.UserDatas).each(function (i, item) {                    userDataShow.push('<div class="btn btn-default">' + item.UserName + '</div>');                });                showMsg("divUsers", userDataShow.join(''), false);            }            ws.onerror = function () {                if (ws) {                    ws.close();                    ws = null;                }                showMsg("divShow", tl.paperDiv("连接服务器-关闭"), true);            }        } catch (e) {            alert(e.message);        }        $("#btnSend").on("click", function () {            var tContentObj = $("#txtContent");            var tContent = $.trim( tContentObj.val()).replace("/[n]/g", "");            var tUserName = $.trim( $("#txtUserName").val()); tUserName = tUserName.length <= 0 ? "匿名" : tUserName;            if (tContent.length <= 0 || $.trim(tContent).length <= 0) { alert("请输入发送内容!"); return; }            if (ws == null) { alert("连接失败,请F5刷新页面!"); return; }            var request = tl.formart('{"UserName": "{0}", "DataType": "{1}", "Msg": "{2}" }',                                     [tUserName, "send", tContent]);            ws.send(request);            tContentObj.val("");            tContentObj.val($.trim(tContentObj.val()).replace("/[n]/g", ""));        });        $("#txtContent").on("keydown", function (event) {            if (event.keyCode == 13) {                $("#btnSend").trigger("click");            }        });    })</script>

  效果图: