http://www.cnblogs.com/wangrudong003/p/5535689.html
go代码部分:
// WebChat project main.go package main import ( "fmt" "net/http" "time" "encoding/json" "strings" "golang.org/x/net/websocket" ) //全局信息 var datas Datas var users map[*websocket.Conn]string func 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(":8080", 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 }
html5代码部分:(index.html 和main.go放置到同一目录)
<!DOCTYPE html> <html lang="zh-CN"> <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 class="container"> <div>内容:</div> <div class="list-group" 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 class="list-group" id="divUsers"> 在线:<br /> <!--<div class="btn btn-default">111</div>--> </div> <div> 昵称:<input class="form-control" id="txtUserName" value="红领巾" type="text" maxlength="20" style="width: 30%; margin-bottom: 15px" /> 聊聊:<textarea class="form-control" 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://127.0.0.1:8080/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>
效果图:
有疑问加站长微信联系(非本文作者)