如果异常断开连接,WebSocket会冻结。

huangapple go评论226阅读模式
英文:

Websocket freezes if disconnected abnormally

问题

我已经为你翻译了代码部分,请查看以下内容:

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()
}

请注意,我只翻译了代码部分,不包括问题描述部分。

英文:

I've created a simple websocket that publishes a JSON stream. I't works fine most of the time except for few cases where I think while looping through the clients to send them message, it gets hung up on a client that is being disconnected abnormally. What measure can I add to this code to mitigate it?

Client.go

import (
    &quot;github.com/gorilla/websocket&quot;
)

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(&quot;Websocket: %s&quot;, 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 (
    &quot;net/http&quot;

    &quot;github.com/gorilla/websocket&quot;
)

const (
    socketBufferSize  = 1024
    messageBufferSize = 256
)

var upgrader = &amp;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 := &lt;-s.join: // joining
		    s.clients[client] = true
	    case client := &lt;-s.leave: // leaving
		    delete(s.clients, client)
		    close(client.send)
	    case msg := &lt;-s.Send: // send message to all clients
		    for client := range s.clients {
			    client.send &lt;- 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 := &amp;client{
	    socket: socket,
	    send:   make(chan *Message, messageBufferSize),
    }

    s.join &lt;- client
    defer func() { s.leave &lt;- client }()

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

答案1

得分: 4

请参考Gorilla Chat Application的示例,了解如何避免在客户端上阻塞。

关键部分包括:

英文:

See the Gorilla Chat Application for an example of how to avoid blocking on a client.

The key parts are:

huangapple
  • 本文由 发表于 2017年7月18日 14:08:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/45158754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定