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