nhooyr websocket: failed to get reader (failed to read frame header: EOF & received close frame: status = StatusPolicyViolation)

Viewed 84

I have this go-gin handler function:
I minimized it to just demo the issue. The problem is that I cannot read/write data simultaneously. I placed a sleep for 5 seconds before writing to websocket. During that time, reading is working fine. As soon as 5 seconds pass and ws tries to write, the reading gives an error as shown below. What could be the issue here?

type DriverWebSocketOutput struct {
    IsBase bool            `json:"is_base"`
    Orders []*models.Order `json:"orders"`
}

func (config *Config) DriverWebSocket(c *gin.Context) {
    ctx := c.Request.Context()
    driverID := auth.GetToken(c).ID()
    driverLoc := &redisclient.DriverLocation{ID: driverID}


    //upgrade http connection to websocket
    wsconn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{InsecureSkipVerify: true})
    if err != nil {
        return
    }
    defer wsconn.Close(websocket.StatusInternalError, "")

    //reading driver location
    go func() {
        for {
            if err := wsjson.Read(ctx, wsconn, &driverLoc.Loc); err != nil {
                if websocket.CloseStatus(err) == websocket.StatusNormalClosure || websocket.CloseStatus(err) == websocket.StatusGoingAway {
                    return
                }
                fmt.Println("err reading driver location", err)//after 5 seconds I get either of:
                //failed to get reader: received close frame: status = StatusPolicyViolation and reason = "unexpected data message"
                //failed to read JSON message: failed to get reader: failed to read frame header: EOF
                break
            }
            fmt.Println("driver location", driverLoc.Loc)// prints data for 5 seconds!
        }
    }()

    //sending order updates to driver
    for {
        out := DriverWebSocketOutput{}//
        time.Sleep(time.Second * 5)
        if err := wsjson.Write(ctx, wsconn, &out); err != nil {
            fmt.Println("err writing to websocket: ", err)
            break
        }

    }
}

In the client side I am using the same lib for testing and those are the functions along with the errors accompanying the above issue.

go func() {
        received := handlers.DriverWebSocketOutput{}
        for {
            if err = wsjson.Read(c.WSContext, wsconn, &received); err != nil {
                fmt.Println(fmt.Sprintf("could not read websocket message: %v", err))
                //failed to read JSON message: failed to get reader: previous message not read to completion
                break
            } 
        }
    }()

    //sending driver location to server
    ticker := time.NewTicker(time.Millisecond * 1000)
    defer ticker.Stop()
loop:
    for {
        select {
        //sending coords to server
        case <-closeRead.Done():
            fmt.Println("server done read")
            break loop
        case t := <-ticker.C:
                    coords := redisclient.Location{Lat: c.Routing.PolylineCoords[c.Routing.I][0], Lng: c.Routing.PolylineCoords[c.Routing.I][1]}
                    if err = wsjson.Write(c.WSContext, wsconn, &coords); err != nil {
                        fmt.Printf("could not send location via websocket: %v\n", err)
                        //failed to write JSON message: failed to get writer: WebSocket closed: failed to get reader: previous message not read to completion
                        break loop
                    }
              }
        }
    }
0 Answers
Related