http.Handle("/", websocket.Handler(EchoServer) Can EchoServer Get another parameter other than ws?

huangapple go评论92阅读模式
英文:

http.Handle("/", websocket.Handler(EchoServer) Can EchoServer Get another parameter other than ws?

问题

我已经打开了一个WebSocket服务器来向Web组件发送数据。

func WebSocketServer() {
    http.Handle("/", websocket.Handler(Echoserver))
    err := http.ListenAndServe(":8081", nil)
    CheckError(err)
}

我想要向处理函数(Echoserver)传递一个额外的参数(类型为String的msg)。

func Echoserver(ws *websocket.Conn, msg string) {
    fmt.Println("Client Connected")
    _ = websocket.JSON.Send(ws, msg)
}

使用上述语法,是否可以实现这个目标?如何调用带有额外参数的Echoserver函数?

英文:

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 ?

答案1

得分: 5

我假设你想要一个在所有连接到/的地方返回一致的string参数。我使用了几种方法。(以下代码示例没有经过测试,如果不能编译,我可以提供一些真实的代码。)

一种方法是让数据成为接收者。我经常在结构体中使用这种方法,但任何参数都可以。这只适用于单个参数(但你当然可以将多个参数放在一个结构体中)。我喜欢这种方法,当参数是"类似对象"时。(通常是一个具有其他方法的结构体。)

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

另一种方法是使用闭包。我喜欢这种方法,当参数是"类似数据"时。(类似字符串或其他简单数据。请注意,这种方法不需要创建本地类型。)

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)
  }
}
英文:

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

答案2

得分: 1

你不能以那种方式传递参数,因为**websocket.Handler**期望一个具有特定签名的函数。

func(*Conn)

这可能是需要使用channel的情况。例如,可以参考这个示例

首先,你的处理函数创建一个channel:

yourHandlerFunction := func(ws *websocket.Conn) {
  client := NewClient(ws, self)
  self.addClient <- client
  client.Listen()
  defer ws.Close()
}

(在这里,一个“Client”是一个包含channel和指向websocket.Conn的指针的结构体)

然后,服务器等待新的客户端,并通过这种方式传递消息:

for {
  select {

    // 添加新的客户端
    case c := <-self.addClient:
      log.Println("Added new client")
      self.clients = append(self.clients, c)
      for _, msg := range self.messages {
        c.Write() <- msg
    }

最后,Client可以接收消息,然后进行JSON调用:

// 通过channel监听写请求
func (self *Client) listenWrite() {
  log.Println("Listening write to client")
  for {
    select {

      // 发送消息给客户端
      case msg := <-self.ch:
        log.Println("Send:", msg)
        websocket.JSON.Send(self.ws, msg)

      // 接收完成请求
      case <-self.done:
        self.server.RemoveClient() <- self
        self.done <- true // 用于listenRead方法
      return
    }
  }
}
英文:

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 &lt;- 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 := &lt;-self.addClient:
      log.Println(&quot;Added new client&quot;)
      self.clients = append(self.clients, c)
      for _, msg := range self.messages {
        c.Write() &lt;- 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(&quot;Listening write to client&quot;)
  for {
    select {

      // send message to the client
      case msg := &lt;-self.ch:
        log.Println(&quot;Send:&quot;, msg)
        websocket.JSON.Send(self.ws, msg)

      // receive done request
      case &lt;-self.done:
        self.server.RemoveClient() &lt;- self
        self.done &lt;- true // for listenRead method
      return
    }
  }
}

huangapple
  • 本文由 发表于 2014年5月21日 18:25:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/23780473.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定