這次的就直接發放代碼截圖吧,應該是用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 }
View Code
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>
效果圖:
主要的備注都寫在代碼裡面了,希望更多的朋友互相分享交流。
git位址:
https://github.com/shenniubuxing3nuget釋出包:
https://www.nuget.org/profiles/shenniubuxing3