gorilla理解如何深入开发聊天

darenwu · · 4326 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

**经过几天奋战,终于学习了gorilla的基本聊天功能,以及对channel简单的理解:** **请求URL:** - ` web:localhost:3000 ` - ` websocket:localhost:3000/ws ` **第一个示例** - ` 这个示例简单的实现了websocket功能,那么我该如何实现聊天功能呢? 看了官网gorilla的chat例子,看了几天头疼,因为面向对象的思想和单进场思想让我对go的这种语法一头雾水,经过几天慢慢体会到了go的一些深意。如何通过channel实现并行,多个channel如何实现。` ``` package main import ( "net/http" "time" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{} func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") }) http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { // 客户端连接链接 var conn, _ = upgrader.Upgrade(w, r, nil) go func(conn *websocket.Conn) { for { // 读取用户信息 _, msg, _ := conn.ReadMessage() // 发送用户信息 conn.WriteJSON("{'user':'" + string(msg) + "'}") } }(conn) }) http.ListenAndServe(":3000", nil) } ``` **第二个示例** ``` package main import ( "fmt" "net/http" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{} type Hub struct { clients map[*Client]bool // *Client addClient chan *Client } var hub = Hub{ clients: make(map[*Client]bool), addClient: make(chan *Client), } func (hub *Hub) start() { fmt.Println("123") for { select { // 读取入channel中的数据(1channel) case conn := <-hub.addClient: hub.clients[conn] = true // 保存客户端连接到map中,这样我就可以实现客户a发送来的信息通过循环这个map发送到其他的客户端 fmt.Println(hub.clients) } } } type Client struct { ws *websocket.Conn } func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") }) // 首先main函数走到这里,将数据保存全局变量里面 go hub.start() http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { // 创建客户端连接 var conn, _ = upgrader.Upgrade(w, r, nil) // 将客户端conn保存在strcut中,为什么要保存在strcut中,也可以不用保存在struct中,为了方便,理解一下struct client := &Client{ws: conn} // 将client写入channel中, 然后保存在map中(1channe) hub.addClient <- client // 但是这里还是没有实现将消息分发到其他客户端,那么我们改怎么办呢? // 我们可以【_, msg, _ := conn.ReadMessage()】读取到的消息(msg变量)写入在channel中,然后通过goruntine方式读取出来 go func(conn *websocket.Conn) { for { // 读取用户信息 _, msg, _ := conn.ReadMessage() // 发送用户信息 conn.WriteJSON("{'user':'" + string(msg) + "'}") } }(conn) }) http.ListenAndServe(":3000", nil) } ``` **第三个示例** ``` package main import ( "fmt" "net/http" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{} type Hub struct { clients map[*Client]bool addClient chan *Client msg chan []byte } var hub = Hub{ clients: make(map[*Client]bool), addClient: make(chan *Client), msg: make(chan []byte), } func (hub *Hub) start() { fmt.Println("123") for { select { // 读取入channel中的数据(1channel) case conn := <-hub.addClient: hub.clients[conn] = true // 保存map fmt.Println(hub.clients) // 读取channel中的数据,这里是获取用户发送的数据(2channel) case msg := <-hub.msg: // 这里循环map里面保存的客户端连接信息 for k, _ := range hub.clients { //发送消息到每一个连接的客户端 k.ws.WriteMessage(1, msg) } } } } type Client struct { ws *websocket.Conn } func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") }) // 首先main函数走到这里,将数据保存全局变量里面 go hub.start() http.HandleFunc("/v1/ws", func(w http.ResponseWriter, r *http.Request) { // 创建客户端连接 var conn, _ = upgrader.Upgrade(w, r, nil) client := &Client{ws: conn} // 将client写入channel中(1channe) hub.addClient <- client // 这里获取客户端发送来的消息 go func(conn *websocket.Conn) { for { _, msg, _ := conn.ReadMessage() //将msg保存在channel中(2channel) hub.msg <- msg } }(conn) }) http.ListenAndServe(":3000", nil) } ``` ** html代码 ** ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="text" placeholder="message" id="textbox"> <button id="button">Send</button> <div id="box"></div> <script> var socket = new WebSocket("ws://localhost:3000/ws"); var button = document.getElementById("button"); button.addEventListener("click", function(event){ var text = document.getElementById("textbox").value; socket.send(text); }); socket.onopen = function(event){ console.log("Socket opened successfully"); } socket.onmessage = function(event){ var box = document.createElement("div"); box.innerHTML = event.data; document.getElementById("box").appendChild(box); } window.onbeforeunload = function(event){ socket.close(); } </script> </body> </html> ``` **备注** - 到这里就简单的实现了聊天功能,这里有一个问题需要学者自己去实现以下,当关闭一个客户端的时候这个程序会崩溃退出,也就是如何将map中保存的客户端删除功能,我相信你行,因为我都行哈哈,初出茅庐求喷!谢谢,祝大家生活愉快!

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4326 次点击  ∙  3 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传