首页 > 其他分享 >go 聊天室

go 聊天室

时间:2023-12-12 10:58:45浏览次数:35  
标签:聊天室 type list var user go data msg

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

相关文章

  • Go Work Stealing 机制
    一、什么是WorkStealingGo语言的WorkStealing机制是一种用于调度协程(Goroutines)的策略,有助于充分利用多核CPU,提高并发性能,降低锁竞争,从而使Go程序更高效地运行WorkStealing机制的核心思想:每个操作系统线程(M)都有一个本地任务队列,它会尽可能地先执行自己队列中的协程。当某......
  • 部署 Argo Rollouts v1.6.3
    创建nsargo-rollouts#kubectlcreatenamespaceargo-rolloutsnamespace/argo-rolloutscreated安装 argo-rollouts#kubectlapply-nargo-rollouts-fhttps://github.com/argoproj/argo-rollouts/releases/latest/download/install.yamlcustomresourcedefinition.api......
  • mongodb
    mongodb内部培训目录简介基础概念适用场景数据建模嵌入式数据模型标准化数据模型N对N关系事务生产经验一般查询符Null大数据量查询索引创建索引索引名称索引类型单字段索引复合索引多键索引索引的属性唯一索引部分索引稀疏索引HiddenInd......
  • Go 语言字符串使用方式与技巧
    Go语言字符串使用方式与技巧原创 frank Golang语言开发栈 2023-12-1023:00 发表于北京收录于合集#Golang语言156个#Golang进阶学习106个大家好,我是frank。欢迎大家点击标题下方蓝色文字「Golang语言开发栈」关注公众号。公众号主页点击右上角三个点图标,设......
  • golang之泛型
    Go1.18版本增加了对泛型的支持,泛型也是自Go语言开源以来所做的最大改变。 泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。ーー换句话说,在编写某些代码或数据结构时先不提供值的类型,而是之后再提供。泛型是一种......
  • Django笔记四十四之Nginx+uWSGI部署Django以及Nginx负载均衡操作
    本文首发于公众号:Hunter后端原文链接:Django笔记四十四之Nginx+uWSGI部署Django以及Nginx负载均衡操作这一篇笔记介绍如何使用Nginx+uWSGI来部署Django。上一篇笔记中有介绍直接使用uWSGI作为web服务器来部署Django,这一篇笔记介绍如何使用Nginx来部署。使用Ngin......
  • golang按换行符一行一行读取GBK文件
    packageawesomeProject1import( "bufio" "fmt" "github.com/axgle/mahonia" "io" "log" "os")funcmain(){ filename:="/tmp/test.txt" readTbkByLine(filename)}funcreadTbkBy......
  • 初中英语优秀范文100篇-023Good Habits Make Me Better -好习惯让我更优秀
    PDF格式公众号回复关键字:SHCZFW023记忆树1Itisessentialtodevelopgoodhabits,whichmakeabigdifferencetoourlife.翻译养成好习惯非常重要,这对我们的生活产生了巨大的影响。简化记忆习惯句子结构主语:It(虚主语)谓语:is(系动词)表语:essential......
  • go-zero开发入门-API网关鉴权开发示例
    本文是go-zero开发入门-API网关开发示例一文的延伸,继续之前请先阅读此文。在项目根目录下创建子目录middleware,在此目录下创建文件auth.go,内容如下://鉴权中间件packagemiddlewareimport("context""errors""net/http")varErrInvalidToken=errors.Ne......
  • Go的Set实现
    Go的Set实现由于Go的内置集合中没有Set的实现,可以用map[type]struct{}要求:1、元素的唯一性2、基本操作:添加、删除、判断是否存在、统计元素数量3、可遍历集合//声明SettypeSetstruct{//利用map,实现的Set集合mapSetmap[string]struct{}}//新增func(s*Set......