I have opened a websocket server to send data to web component,
func WebSocketServer() {
http.Handle("/", websocket.Handler(Echoserver))
err := http.ListenAndServe(":8081", nil)
CheckError(err)
}
I would like to pass an additionnal argument (msg, of type String) to the handlerfunction (Echoserver).
func Echoserver(ws *websocket.Conn, msg String) {
fmt.Println("Client Connected")
_ := websocket.JSON.Send(ws, msg);
}
}
Is it possible to do this with the syntax above? How do you call Echoserver with the additionnal parameter ?
I assume what you want here is a consistent string
parameter that is returned for all connections to /. There are a couple of approaches I've used. (None of these specific code samples have been tested; I can pull some real code if they don't compile.)
One is to let the data be the receiver. I use this a most often with a struct, but any parameter will do. This only works for a single parameter (but you could of course put multiple parameters in a struct). I like this approach when the parameter is "object like." (Generally a struct that has other methods on it.)
type echoStuff string
var hey echoStuff = "Hey!"
http.Handle("/", websocket.Handler(hey.EchoServer))
err := http.ListenAndServe(":8081", nil)
CheckError(err)
func (msg echoStuff) Echoserver(ws *websocket.Conn) {
fmt.Println("Client Connected")
_ := websocket.JSON.Send(ws, msg);
}
Another way is with a closure. I like this approach when the parameter is "data like." (Something like a string or other simple data. Note how this approach doesn't require creating a local type.)
func WebSocketServer() {
http.Handle("/", echoHandler("Hey!"))
err := http.ListenAndServe(":8081", nil)
CheckError(err)
}
func echoHandler(msg string) websocket.Handler {
return func(ws *Conn) {
Echoserver(ws, msg)
}
}
You shouldn't be able to pass a parameter that way since a websocket.Handler
expect a function with a specific signature.
func(*Conn)
This is probably a situation where channel are called for.
See this example for instance:
First, your handler function creates a channel:
yourHandlerFunction := func(ws *websocket.Conn) {
client := NewClient(ws, self)
self.addClient <- client
client.Listen()
defer ws.Close()
}
(Here, a "Client" is a struct which includes a channel and a pointer to the websocket.Conn
)
Then the server waits for a new client, and pass a message that way:
for {
select {
// Add new a client
case c := <-self.addClient:
log.Println("Added new client")
self.clients = append(self.clients, c)
for _, msg := range self.messages {
c.Write() <- msg
}
Finally, the Client can receive the message, and then make the JSON call:
// Listen write request via chanel
func (self *Client) listenWrite() {
log.Println("Listening write to client")
for {
select {
// send message to the client
case msg := <-self.ch:
log.Println("Send:", msg)
websocket.JSON.Send(self.ws, msg)
// receive done request
case <-self.done:
self.server.RemoveClient() <- self
self.done <- true // for listenRead method
return
}
}
}