When writing a websocket server in GO (in my case using the JSON codec), is it safe to have two different Go routines for handling sending and receiving of data on the same connection?
Since websocket.JSON.Receive
pauses and waits to receive data, I thought a separate Go routine for handling sending of data would be a working solution unless concurrent sending/receiving is not possible on the same connection.
So, is the working example below bad practice?
package main
import (
"fmt"
"net/http"
"code.google.com/p/go.net/websocket"
)
const queueSize = 20
type Input struct {
Cmd string
}
type Output struct {
Cmd string
}
func Handler(ws *websocket.Conn) {
msgWrite := make(chan *Output, queueSize)
var in Input
go writeHandler(ws, msgWrite)
for {
err := websocket.JSON.Receive(ws, &in)
if err != nil {
fmt.Println(err)
break
} else {
msgWrite <- &Output{Cmd: "Thanks for your message: " + in.Cmd}
}
}
}
func writeHandler(ws *websocket.Conn, out chan *Output) {
var d *Output
for {
select {
case d = <-out:
if err := websocket.JSON.Send(ws, &d); err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("> ", d.Cmd)
}
}
}
}
func main() {
http.Handle("/echo", websocket.Handler(Handler));
err := http.ListenAndServe(":1235", nil);
if err != nil {
panic("ListenAndServe: " + err.Error())
}
fmt.Println("Server running")
}
Yes, you can call Send, Receive and Close on a websocket connection concurrently, like you can with all net.Conn's in Go. A short excerpt from the official docs:
Multiple goroutines may invoke methods on a Conn simultaneously.
Additionally, the websocket package also introduces some Codecs for sending / writing Messages or JSON data that might occupy multiple frames atomically. If you look at the source, you can see that the Send and Receive method of the Codec type will hold either the read or the write lock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With