Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is websocket Send/Receive thread-safe (go routine-safe)?

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")
}
like image 295
ANisus Avatar asked Jun 11 '12 19:06

ANisus


1 Answers

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.

like image 114
tux21b Avatar answered Sep 24 '22 19:09

tux21b