main.go
1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/gorilla/websocket" 9 "github.com/gorilla/mux" 10 ) 11 12 type Data struct { 13 Ip string `json:"ip"` 14 User string `json:"user"` 15 From string `json:"from"` 16 Type string `json:"type"` 17 Content string `json:"content"` 18 UserList []string `json:"user_list"` 19 } 20 21 type connection struct { 22 ws *websocket.Conn 23 sc chan []byte 24 data *Data 25 } 26 27 type hub struct { 28 c map[*connection]bool 29 b chan []byte 30 r chan *connection 31 u chan *connection 32 } 33 34 var h = hub{ 35 c: make(map[*connection]bool), 36 b: make(chan []byte), 37 r: make(chan *connection), 38 u: make(chan *connection), 39 } 40 41 func (h *hub) run(){ 42 for { 43 select { 44 case c:= <-h.r: 45 h.c[c] = true 46 c.data.Ip = c.ws.RemoteAddr().String() 47 c.data.Type = "handshake" 48 c.data.UserList = user_list 49 data_b, _ := json.Marshal(c.data) 50 c.sc <- data_b 51 case c:= <-h.u: 52 fmt.Println(h.u) 53 if _, ok := h.c[c]; ok { 54 delete(h.c, c) 55 close(c.sc) 56 } 57 case data := <-h.b: 58 for c := range h.c { 59 select { 60 case c.sc <- data: 61 default: 62 delete(h.c, c) 63 close(c.sc) 64 } 65 } 66 } 67 } 68 } 69 70 var wu = &websocket.Upgrader{ReadBufferSize:512, 71 WriteBufferSize: 512, CheckOrigin: func(r *http.Request) bool { return true }} 72 73 func myws(w http.ResponseWriter, r *http.Request) { 74 ws, err := wu.Upgrade(w, r, nil) 75 if err != nil { 76 return 77 } 78 c := &connection{sc: make(chan []byte, 256), ws: ws, data: &Data{}} 79 h.r <- c 80 go c.writer() 81 c.reader() 82 defer func() { 83 84 c.data.Type = "logout" 85 user_list = del(user_list, c.data.User) 86 c.data.UserList = user_list 87 c.data.Content = c.data.User 88 data_b, _ := json.Marshal(c.data) 89 h.b <- data_b 90 h.r <- c 91 }() 92 } 93 94 func (c *connection) writer() { 95 for message := range c.sc { 96 c.ws.WriteMessage(websocket.TextMessage, message) 97 } 98 c.ws.Close() 99 } 100 101 var user_list = []string{} 102 103 func (c *connection) reader() { 104 for { 105 _, message, err := c.ws.ReadMessage() 106 if err != nil { 107 h.r <- c 108 break 109 } 110 json.Unmarshal(message, &c.data) 111 switch c.data.Type { 112 case "login": 113 c.data.User = c.data.Content 114 c.data.From = c.data.User 115 user_list = append(user_list, c.data.User) 116 c.data.UserList = user_list 117 data_b, _ := json.Marshal(c.data) 118 h.b <- data_b 119 case "user": 120 c.data.Type = "user" 121 data_b, _ := json.Marshal(c.data) 122 h.b <- data_b 123 case "logout": 124 c.data.Type = "logout" 125 user_list = del(user_list, c.data.User) 126 data_b, _ := json.Marshal(c.data) 127 h.b <- data_b 128 h.r <- c 129 default: 130 fmt.Print("========default================") 131 } 132 } 133 } 134 135 func del(slice []string, user string) []string { 136 count := len(slice) 137 if count == 0 { 138 return slice 139 } 140 if count == 1 && slice[0] == user { 141 return []string{} 142 } 143 var n_slice = []string{} 144 for i := range slice { 145 if slice[i] == user && i == count { 146 return slice[:count] 147 } else if slice[i] == user { 148 n_slice = append(slice[:i], slice[i+1:]...) 149 break 150 } 151 } 152 fmt.Println(n_slice) 153 return n_slice 154 } 155 156 157 func main() { 158 router := mux.NewRouter() 159 go h.run() 160 router.HandleFunc("/ws", myws) 161 if err := http.ListenAndServe("127.0.0.1:8080", router); err != nil { 162 fmt.Println("err:", err) 163 } 164 }
local.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <meta http-equiv="content-type" content="text/html;charset=utf-8"> 6 <style> 7 p { 8 text-align: left; 9 padding-left: 20px; 10 } 11 </style> 12 </head> 13 <body> 14 <div style="width: 800px;height: 600px;margin: 30px auto;text-align: center"> 15 <h1>www.5lmh.comy演示聊天室</h1> 16 <div style="width: 800px;border: 1px solid gray;height: 300px;"> 17 <div style="width: 200px;height: 300px;float: left;text-align: left;"> 18 <p><span>当前在线:</span><span id="user_num">0</span></p> 19 <div id="user_list" style="overflow: auto;"> 20 </div> 21 </div> 22 <div id="msg_list" style="width: 598px;border: 1px solid gray; height: 300px;overflow: scroll;float: left;"> 23 </div> 24 </div> 25 <br> 26 <textarea id="msg_box" rows="6" cols="50" onkeydown="confirm(event)"></textarea><br> 27 <input type="button" value="发送" onclick="send()"> 28 </div> 29 </body> 30 </html> 31 <script type="text/javascript"> 32 var uname = prompt('请输入用户名', 'user' + uuid(8, 16)); 33 var ws = new WebSocket("ws://127.0.0.1:8080/ws"); 34 ws.onopen = function () { 35 var data = "系统消息:建立连接成功"; 36 listMsg(data); 37 }; 38 ws.onmessage = function (e) { 39 console.log(e.data) 40 console.log(e) 41 42 var msg = JSON.parse(e.data); 43 var sender, user_name, name_list, change_type; 44 switch (msg.type) { 45 case 'system': 46 sender = '系统消息: '; 47 break; 48 case 'user': 49 sender = msg.from + ': '; 50 break; 51 case 'handshake': 52 var user_info = {'type': 'login', 'content': uname}; 53 sendMsg(user_info); 54 return; 55 case 'login': 56 case 'logout': 57 user_name = msg.content; 58 name_list = msg.user_list; 59 change_type = msg.type; 60 dealUser(user_name, change_type, name_list); 61 return; 62 } 63 var data = sender + msg.content; 64 listMsg(data); 65 }; 66 ws.onerror = function () { 67 var data = "系统消息 : 出错了,请退出重试."; 68 listMsg(data); 69 }; 70 function confirm(event) { 71 var key_num = event.keyCode; 72 if (13 == key_num) { 73 send(); 74 } else { 75 return false; 76 } 77 } 78 function send() { 79 var msg_box = document.getElementById("msg_box"); 80 var content = msg_box.value; 81 var reg = new RegExp("\r\n", "g"); 82 content = content.replace(reg, ""); 83 var msg = {'content': content.trim(), 'type': 'user'}; 84 sendMsg(msg); 85 msg_box.value = ''; 86 } 87 function listMsg(data) { 88 var msg_list = document.getElementById("msg_list"); 89 var msg = document.createElement("p"); 90 msg.innerHTML = data; 91 msg_list.appendChild(msg); 92 msg_list.scrollTop = msg_list.scrollHeight; 93 } 94 function dealUser(user_name, type, name_list) { 95 var user_list = document.getElementById("user_list"); 96 var user_num = document.getElementById("user_num"); 97 while(user_list.hasChildNodes()) { 98 user_list.removeChild(user_list.firstChild); 99 } 100 for (var index in name_list) { 101 var user = document.createElement("p"); 102 user.innerHTML = name_list[index]; 103 user_list.appendChild(user); 104 } 105 user_num.innerHTML = name_list.length; 106 user_list.scrollTop = user_list.scrollHeight; 107 var change = type == 'login' ? '上线' : '下线'; 108 var data = '系统消息: ' + user_name + ' 已' + change; 109 listMsg(data); 110 } 111 function sendMsg(msg) { 112 var data = JSON.stringify(msg); 113 ws.send(data); 114 } 115 function uuid(len, radix) { 116 var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 117 var uuid = [], i; 118 radix = radix || chars.length; 119 if (len) { 120 for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; 121 } else { 122 var r; 123 uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; 124 uuid[14] = '4'; 125 for (i = 0; i < 36; i++) { 126 if (!uuid[i]) { 127 r = 0 | Math.random() * 16; 128 uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; 129 } 130 } 131 } 132 return uuid.join(''); 133 } 134 </script>View Code
标签:聊天室,type,list,var,user,go,data,msg From: https://www.cnblogs.com/HHMLXL/p/17896271.html