2017-07-18 90 views
0

我已经创建了一个简单的websocket发布JSON流。我大部分时间都工作得很好,除了少数情况下,我认为在循环客户端发送消息时,它会挂在正在异常断开连接的客户端上。我可以添加什么措施来减轻这个代码?Websocket冻结,如果断开异常

Client.go

import (
    "github.com/gorilla/websocket" 
) 

type client struct { 
    socket *websocket.Conn 

    send chan *Message 
} 

func (c *client) read() { 
    defer c.socket.Close() 
    for { 
     _, _, err := c.socket.ReadMessage() 
     if err != nil { 
      log.Info("Websocket: %s", err) 
      break 
     } 
    } 
} 

func (c *client) write() { 
    defer c.socket.Close() 
    for msg := range c.send { 
     err := c.socket.WriteJSON(msg) 
     if err != nil { 
      break 
     } 
    } 
} 

Stream.go

import (
    "net/http" 

    "github.com/gorilla/websocket" 
) 

const (
    socketBufferSize = 1024 
    messageBufferSize = 256 
) 

var upgrader = &websocket.Upgrader{ 
    ReadBufferSize: socketBufferSize, 
    WriteBufferSize: socketBufferSize, 
} 

type Stream struct { 
    Send chan *Message 

    join chan *client 

    leave chan *client 

    clients map[*client]bool 
} 

func (s *Stream) Run() { 
    for { 
     select { 
     case client := <-s.join: // joining 
      s.clients[client] = true 
     case client := <-s.leave: // leaving 
      delete(s.clients, client) 
      close(client.send) 
     case msg := <-s.Send: // send message to all clients 
      for client := range s.clients { 
       client.send <- msg 
      } 
     } 
    } 
} 

func (s *Stream) ServeHTTP(w http.ResponseWriter, res *http.Request) { 
    socket, err := upgrader.Upgrade(w, res, nil) 
    if err != nil { 
     log.Error(err) 
     return 
    } 

    defer func() { 
     socket.Close() 
    }() 

    client := &client{ 
     socket: socket, 
     send: make(chan *Message, messageBufferSize), 
    } 

    s.join <- client 
    defer func() { s.leave <- client }() 

    go client.write() 
    client.read() 
}   

回答

2

关于如何避免阻塞客户机上的示例,请参见Gorilla Chat Application

的关键部分是:

+0

谢谢你所有的指针。 – Daniyal