simple-chatroom
simple-chatroom copied to clipboard
conn 放入 client 的里面去读会有问题
client方法里面使用conn链接readjson会出现 use of closed network connection和 读取消息为空的问题。
能描述一下具体出现问题的条件吗?
我将我的代码主要相关的部分移到了一个文件,以便来查找相关问题。如下: `package main
import ( "fmt" "github.com/gorilla/websocket" "imChong/module" "log" "net/http" )
var upgrader = websocket.Upgrader{}
type Client struct {
UserId string
Connection *websocket.Conn
Send chan Message
}
type Message struct {
//Username string json:"username"
Message string json:"message"
ToUserId string json:"to_user_id"
UserId string json:"user_id"
GroupId string json:"group_id"
}
func main() { http.HandleFunc("/", NewConn) err := http.ListenAndServe("192.168.0.103:3000", nil) if err != nil { log.Fatal("ListenAndServe: ", err) } }
// 新建连接 func NewConn(w http.ResponseWriter, r *http.Request) { //不检查来源 upgrader.CheckOrigin = func(r *http.Request) bool { return true } ws, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("https升级为wss失败:err:") log.Fatal(err) } userId := r.URL.Query().Get("id") // 用户id
defer func() {
err := ws.Close()
if err != nil {
fmt.Println("链接时 断开:")
fmt.Println(userId)
fmt.Println(err)
// 发送消息通知
return
}
}()
//链接
if len(userId) > 0 && userId != "0" {
client := module.NewClient(ws, userId)
go client.ReadMessage()
go client.WriteMessage()
//for {
// msg := module.Message{}
// err := ws.ReadJSON(&msg)
// if err != nil {
// log.Print("这个ws读取消息时错误,将连接移除")
// log.Print(userId)
// log.Print(err)
// return
// }
// log.Print(msg)
//}
}
}
func NewClient(conn *websocket.Conn, userId string) *Client { return &Client{ UserId: userId, Connection: conn, Send: make(chan Message), } }
func (c *Client) ReadMessage() { for { msg := Message{} err := c.Connection.ReadJSON(&msg) log.Print(msg) log.Print(c.Connection) if err != nil { log.Print("这个ws读取消息时错误,将连接移除") log.Print(err) } }
}
func (c *Client) WriteMessage() { for { msg := <-c.Send // 发送消息给 链接 if err := c.Connection.WriteJSON(msg); err != nil { log.Print("关闭链接") log.Print(err) err := c.Connection.Close() if err != nil { log.Print("写消息时关闭链接失败") log.Print(err) } } } } ` 我把 启动协程去读取消息 改为在当前环境直接读取就没问题了,我今天在找寻其中的原因。 如果你能发现其中的问题,希望能告知,谢谢~~
格式调整了 上传还是有点乱,可以直接复制到ide运行哈
原来是这样。。。
你这段代码如果使用协程去处理那么
go client.ReadMessage()
go client.WriteMessage()
这两句走完之后是不会阻塞的,会直接走到defer func从而将连接关闭,就会出现问题;而当你使用for去处理的时候,被阻塞了,一直在循环,所以不会被关闭,所以就没有问题
难怪,我刚刚把后面逻辑的group <- client 加上好像好了,应该主协程退出的原因。 非常谢谢你,希望能加你一个联系方式。如此低级的问题浪费你时间了~我微-信:hb824871515
没事,小问题