调用TCP发送(网络包)从HTTP请求函数。

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

Call TCP send (net package) from http request function

问题

我是Go的新手,遇到了一个问题:我的程序接收到一个HTTP POST请求,现在我想将其中的数据转发到一个活动的TCP连接(程序运行一个并行的TCP服务器)。
main()函数中,处理程序被注册如下:
http.HandleFunc("/rcvtelegram", handleRestRequest)

因此,HTTP处理函数如下:

func handleRestRequest(w http.ResponseWriter, r *http.Request) {}

与客户端的TCP连接是通过net.Conn对象打开的,main()函数知道这一点。所以理想情况下,我会启动一个goroutine,其中包含一个TCP发送函数,该函数监听传入的字符串并通过TCP发送它。但是如何实现呢?使用通道似乎需要传递所有参数,但在HTTP处理程序函数中我没有连接对象。我还想避免将TCP连接变成全局变量。我看到了观察者模式,但作为一个新手,我对其复杂性感到担忧(而且不确定它是否解决了我的问题)。

谢谢!

英文:

I'm new to Go - following problem: My program receives an http post request and now I want to forward data from it to an active TCP connection (the program runs a parallel TCP Server).
In main() the handler is registered like this:
http.HandleFunc("/rcvtelegram", handleRestRequest)

and the http-handler function is therefore like this:

func handleRestRequest(w http.ResponseWriter, r *http.Request) {}

The TCP connection to the client is open with a net.Conn object which main() knows. So ideally I would start a go routine with a TCP sender function that listens for an incoming string to send it through TCP. But how? With channels it seems I must pass all parameters but I don't have the connection object in the http handler function. I also want to avoid making the tcp connection a global variable. I saw the Observer pattern but that scares me with its complexity as a newbie (and not sure if it solves my problem).

Thanks!

答案1

得分: 0

使用结构体类型来保存通道。在该类型上实现http.Handler接口:

type RestHandler struct {
    ch chan string
}

func (h *RestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // 在这里插入handleRestRequest的代码。
    // 使用 h.ch <- someString 将字符串发送到连接。
}

在主函数中,为TCP发送器创建一个通道,并在一个goroutine中启动发送器:

ch := make(chan string)
go tcpSender(ch)

使用通道创建一个*RestHandler的值,并将其注册为处理程序:

http.Handle("/rcvtelegram", &RestHandler{ch: ch})
英文:

Use a struct type to hold the channel. Implement the http.Handler interface on the type:

type RestHandler struct {
	ch chan string
}

func (h *RestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// insert body of the handleRestRequest here.
	// Use h.ch &lt;- someString to send string to connection
}

In your main function, create a channel for the TCP sender and start the sender in a goroutine:

ch := make(chan string)
go tcpSender(ch)

Create a value of *RestHandler with the channel and register it as the handler:

http.Handle(&quot;/rcvtelegram&quot;, &amp;RestHandler{ch:ch})

答案2

得分: 0

根据上述提议,我按照以下方式构建了它:

type TcpHandler struct {
    connection net.Conn
}

func (t TcpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {...}

httpTcpHandler := TcpHandler{connection: conn}
mux := http.NewServeMux()
mux.Handle("/rcvtelegram", httpTcpHandler)
go startHttpServer(httpPort, mux)

它按预期工作!

英文:

Based on above proposal I built it this way:

type TcpHandler struct {
	connection net.Conn
}

Then defined a custom HTTP Handler:

func (t TcpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {...}

Then registered it with the existing TCP connection in main():

httpTcpHandler := TcpHandler{connection: conn}
mux := http.NewServeMux()
mux.Handle(&quot;/rcvtelegram&quot;, httpTcpHandler)
go startHttpServer(httpPort, mux)

Works as it should!

huangapple
  • 本文由 发表于 2022年5月22日 23:06:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/72338760.html
匿名

发表评论

匿名网友

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

确定