这次的就直接发放代码截图吧,应该是用go语言做后台一个简易的聊天,这里没用到什么特别的知识,最朴实的来实现效果,主要目的是分享下h5怎么用websocket,go搭建websocket服务的主要部分。
go代码部分:
1 // WebChat project main.go 2 package main 3 4 import ( 5 "fmt" 6 "net/http" 7 "time" 8 9 "encoding/json" 10 11 "strings" 12 13 "golang.org/x/net/websocket" 14 ) 15 16 //全局信息 17 var datas Datas 18 var users map[*websocket.Conn]string 19 20 func main() { 21 fmt.Println("启动时间") 22 fmt.Println(time.Now()) 23 24 //初始化 25 datas = Datas{} 26 users = make(map[*websocket.Conn]string) 27 28 //绑定效果页面 29 http.HandleFunc("/", h_index) 30 //绑定socket方法 31 http.Handle("/webSocket", websocket.Handler(h_webSocket)) 32 //开始监听 33 http.ListenAndServe(":8", nil) 34 } 35 36 func h_index(w http.ResponseWriter, r *http.Request) { 37 38 http.ServeFile(w, r, "index.html") 39 } 40 41 func h_webSocket(ws *websocket.Conn) { 42 43 var userMsg UserMsg 44 var data string 45 for { 46 47 //判断是否重复连接 48 if _, ok := users[ws]; !ok { 49 users[ws] = "匿名" 50 } 51 userMsgsLen := len(datas.UserMsgs) 52 fmt.Println("UserMsgs", userMsgsLen, "users长度:", len(users)) 53 54 //有消息时,全部分发送数据 55 if userMsgsLen > 0 { 56 b, errMarshl := json.Marshal(datas) 57 if errMarshl != nil { 58 fmt.Println("全局消息内容异常...") 59 break 60 } 61 for key, _ := range users { 62 errMarshl = websocket.Message.Send(key, string(b)) 63 if errMarshl != nil { 64 //移除出错的链接 65 delete(users, key) 66 fmt.Println("发送出错...") 67 break 68 } 69 } 70 datas.UserMsgs = make([]UserMsg, 0) 71 } 72 73 fmt.Println("开始解析数据...") 74 err := websocket.Message.Receive(ws, &data) 75 fmt.Println("data:", data) 76 if err != nil { 77 //移除出错的链接 78 delete(users, ws) 79 fmt.Println("接收出错...") 80 break 81 } 82 83 data = strings.Replace(data, "\n", "", 0) 84 err = json.Unmarshal([]byte(data), &userMsg) 85 if err != nil { 86 fmt.Println("解析数据异常...") 87 break 88 } 89 fmt.Println("请求数据类型:", userMsg.DataType) 90 91 switch userMsg.DataType { 92 case "send": 93 //赋值对应的昵称到ws 94 if _, ok := users[ws]; ok { 95 users[ws] = userMsg.UserName 96 97 //清除连接人昵称信息 98 datas.UserDatas = make([]UserData, 0) 99 //重新加载当前在线连接人 100 for _, item := range users { 101 102 userData := UserData{UserName: item} 103 datas.UserDatas = append(datas.UserDatas, userData) 104 } 105 } 106 datas.UserMsgs = append(datas.UserMsgs, userMsg) 107 } 108 } 109 110 } 111 112 type UserMsg struct { 113 UserName string 114 Msg string 115 DataType string 116 } 117 118 type UserData struct { 119 UserName string 120 } 121 122 type Datas struct { 123 UserMsgs []UserMsg 124 UserDatas []UserData 125 }
html代码部分:
1 <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <title></title> 5 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> 6 <!-- 新 Bootstrap 核心 CSS 文件 --> 7 <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"> 8 <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> 9 <!-- <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>--> 10 </head> 11 <body> 12 <div class="container"> 13 <div>内容:</div> 14 <div class="list-group" id="divShow"> 15 <!--<div class="list-group-item list-group-item-success">1111</div> 16 <div class="list-group-item list-group-item-info">1111</div> 17 <div class="list-group-item list-group-item-warning">1111</div> 18 <div class="list-group-item list-group-item-danger">1111</div>--> 19 </div> 20 <div class="list-group" id="divUsers"> 21 在线:<br /> 22 <!--<div class="btn btn-default">111</div>--> 23 24 </div> 25 <div> 26 昵称:<input class="form-control" id="txtUserName" value="红领巾" type="text" maxlength="20" style="width: 30%; margin-bottom: 15px" /> 27 聊聊:<textarea class="form-control" id="txtContent" autofocus rows="6" placeholder="想聊的内容" maxlength="200" required style="width: 60%; "></textarea> 28 <button class="btn btn-default" id="btnSend" style="margin-top:15px">发 送</button> 29 </div> 30 </div> 31 </body> 32 </html> 33 34 <script> 35 36 var tool = function () { 37 38 var paperLoopNum = 0; 39 var paperTempleArr = [ 40 '<div class="list-group-item list-group-item-success">{0}</div>', 41 '<div class="list-group-item list-group-item-info">{0}</div>', 42 '<div class="list-group-item list-group-item-warning">{0}</div>', 43 '<div class="list-group-item list-group-item-danger">{0}</div>' 44 ]; 45 46 return { 47 48 paperDiv: function (val) { 49 50 var hl = paperTempleArr[paperLoopNum]; 51 paperLoopNum++; 52 if (paperLoopNum >= paperTempleArr.length) { paperLoopNum = 0; } 53 54 return this.formart(hl, [val]) 55 }, 56 formart: function (str, arrVal) { 57 58 for (var i = 0; i < arrVal.length; i++) { 59 str = str.replace("{" + i + "}", arrVal[i]); 60 } 61 return str; 62 } 63 } 64 } 65 66 function showMsg(id, hl, isAppend) { 67 68 if (!isAppend) { $("#" + id).html(hl); } else { 69 $("#" + id).append(hl); 70 } 71 } 72 73 $(function () { 74 75 //初始化工具方法 76 var tl = new tool(); 77 78 var wsUrl = "ws://172.16.9.6:8/webSocket"; 79 ws = new WebSocket(wsUrl); 80 81 try { 82 83 ws.onopen = function () { 84 85 //showMsg("divShow", tl.paperDiv("连接服务器-成功")); 86 } 87 88 ws.onclose = function () { 89 if (ws) { 90 ws.close(); 91 ws = null; 92 } 93 showMsg("divShow", tl.paperDiv("连接服务器-关闭"), true); 94 } 95 96 ws.onmessage = function (result) { 97 98 //console.log(result.data); 99 var data = JSON.parse(result.data); 100 $(data.UserMsgs).each(function (i, item) { 101 showMsg("divShow", tl.paperDiv("【" + item.UserName + "】:" + item.Msg), true); 102 }); 103 104 var userDataShow = []; 105 $(data.UserDatas).each(function (i, item) { 106 107 userDataShow.push('<div class="btn btn-default">' + item.UserName + '</div>'); 108 109 }); 110 showMsg("divUsers", userDataShow.join(''), false); 111 } 112 113 ws.onerror = function () { 114 if (ws) { 115 ws.close(); 116 ws = null; 117 } 118 showMsg("divShow", tl.paperDiv("连接服务器-关闭"), true); 119 } 120 121 } catch (e) { 122 123 alert(e.message); 124 } 125 $("#btnSend").on("click", function () { 126 127 var tContentObj = $("#txtContent"); 128 var tContent = $.trim( tContentObj.val()).replace("/[\n]/g", ""); 129 var tUserName = $.trim( $("#txtUserName").val()); tUserName = tUserName.length <= 0 ? "匿名" : tUserName; 130 if (tContent.length <= 0 || $.trim(tContent).length <= 0) { alert("请输入发送内容!"); return; } 131 if (ws == null) { alert("连接失败,请F5刷新页面!"); return; } 132 133 var request = tl.formart('{"UserName": "{0}", "DataType": "{1}", "Msg": "{2}" }', 134 [tUserName, "send", tContent]); 135 ws.send(request); 136 tContentObj.val(""); 137 tContentObj.val($.trim(tContentObj.val()).replace("/[\n]/g", "")); 138 }); 139 $("#txtContent").on("keydown", function (event) { 140 141 if (event.keyCode == 13) { 142 143 $("#btnSend").trigger("click"); 144 } 145 }); 146 }) 147 148 </script>
效果图:
主要的备注都写在代码里面了,希望更多的朋友相互分享交流。