基于go websocket写一个聊天室
来源:互联网 发布:mac的邮箱怎么设置 编辑:程序博客网 时间:2024/05/21 17:56
上一篇介绍了一下go websocket,这篇blog主要是通过websocket写一个聊天室。
先写前端
</style></head><body><div id="log"></div><form id="form"> <input type="submit" value="Send" /> <input type="text" id="msg" size="64"/></form></body></html>
这里面有三个组件,一个log记录,一个是msg消息发送,一个是发送按钮。下面给这个两个组件添加事件,
<script type="text/javascript">window.onload = function () { var conn; var msg = document.getElementById("msg"); var log = document.getElementById("log"); function appendLog(item) { var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1; log.appendChild(item); if (doScroll) { log.scrollTop = log.scrollHeight - log.clientHeight; } } document.getElementById("form").onsubmit = function () { if (!conn) { return false; } if (!msg.value) { return false; } conn.send(msg.value); msg.value = ""; return false; }; if (window["WebSocket"]) { conn = new WebSocket("ws://" + document.location.host + "/ws"); conn.onclose = function (evt) { var item = document.createElement("div"); item.innerHTML = "<b>Connection closed.</b>"; appendLog(item); }; conn.onmessage = function (evt) { var messages = evt.data.split('\n'); for (var i = 0; i < messages.length; i++) { var item = document.createElement("div"); item.innerText = messages[i]; appendLog(item); } }; } else { var item = document.createElement("div"); item.innerHTML = "<b>Your browser does not support WebSockets.</b>"; appendLog(item); }};</script>
这个里面先对发送按钮添加事件,每当按下时候执行send,将数据发送到后端;当后端发送数据到前端,就执行appendLog追加内容。好了,介绍完这个就介绍后端。后端里面先介绍主程序
func main() { flag.Parse() hub := newHub() go hub.run() http.HandleFunc("/", serveHome) http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { serveWs(hub, w, r) }) err := http.ListenAndServe(*addr, nil) if err != nil { log.Fatal("ListenAndServe: ", err) }}
这个里面hub是一个消息的分发器,就是把消息发送到每个客户端。这个里面把消息广播到每个聊天的client。
func (h *Hub) run() { for { select { case client := <-h.register: h.clients[client] = true case client := <-h.unregister: if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } case message := <-h.broadcast: for client := range h.clients { select { case client.send <- message: default: close(client.send) delete(h.clients, client) } } } }}
还有一个是serverWs的实现
go client.writePump() go client.readPump()
就是负责client的读和写。
func (c *Client) readPump() { defer func() { c.hub.unregister <- c c.conn.Close() }() c.conn.SetReadLimit(maxMessageSize) c.conn.SetReadDeadline(time.Now().Add(pongWait)) c.conn.SetPongHandler(func(string) error { c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) for { _, message, err := c.conn.ReadMessage() if err != nil { if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { log.Printf("error: %v", err) } break } message = bytes.TrimSpace(bytes.Replace(message, newline, space, -1)) c.hub.broadcast <- message }}
读很简单,通过ReadMessage读取
写也是类似,
func (c *Client) writePump() { ticker := time.NewTicker(pingPeriod) defer func() { ticker.Stop() c.conn.Close() }() for { select { case message, ok := <-c.send: c.conn.SetWriteDeadline(time.Now().Add(writeWait)) if !ok { // The hub closed the channel. c.conn.WriteMessage(websocket.CloseMessage, []byte{}) return } w, err := c.conn.NextWriter(websocket.TextMessage) if err != nil { return } w.Write(message) // Add queued chat messages to the current websocket message. n := len(c.send) for i := 0; i < n; i++ { w.Write(newline) w.Write(<-c.send) } if err := w.Close(); err != nil { return } case <-ticker.C: c.conn.SetWriteDeadline(time.Now().Add(writeWait)) if err := c.conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } }}
那么这个聊天室就写好了。
阅读全文
0 0
- 基于go websocket写一个聊天室
- 使用 Go 语言和 HTML5 WebSocket 构建一个 Web 聊天室
- 基于websocket,使用node.js 做一个聊天室
- 基于WebSocket的简易聊天室
- java websocket 建立一个聊天室
- 基于node的websocket学习笔记二:一个简单的聊天室程序与优化方案
- HTML5 WebSocket做聊天室(服务器端基于Jetty8)
- 基于Jetty服务器的Websocket聊天室
- HTML5 WebSocket做聊天室(服务器端基于Jetty8)
- HTML5 WebSocket做聊天室(服务器端基于Jetty8)
- 基于spring4 websocket的简易聊天室
- 基于websocket的多人页面聊天室
- 基于websocket的简易聊天室的实现
- SSM(五)基于webSocket的聊天室
- websocket聊天室,简单版本,基于swoole
- 基于 SpringBoot 和 webSocket 的匿名聊天室
- php基于websocket实现的在线聊天室
- SSM(五)基于webSocket的聊天室
- SQL 笛卡尔积
- 5.3
- mysql设置远程访问
- elasticsearch-java api中get() 和execute().actionGet()方法
- //& && 、| || 的区别
- 基于go websocket写一个聊天室
- LeetCode 674.Longest Continuous Increasing Subsequence
- python将代码转换成网页
- java反射学习摘记
- 1.1初识Java
- Linux系统-常见的文件操作命令
- 机器学习笔记之三: 熵
- 使用Maven管理Mybatis项目之pom文件配置
- 使用Docker中的mysql