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

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

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:

确定