2017-04-26 1 views
-1

golang으로 작성된 rest-ful 인터페이스가 있습니다. 각 끝점에서 인증을 수행해야합니다. 인증이 완료되면 다시 TCP 서버로 전달해야합니다. tcp 클라이언트를 만들었으며 채널에서 오는 모든 값을 tcp 서버에 보내야합니다. 채널은 http 요청 본문에서 채워집니다. 문제는 말괄량이 명령을 실행하면 클라이언트가 응답없이 멈추는 것입니다. 그래서 분명히 무엇이 잘못되었는지를 잘못 판단하고 있습니다. 누구든지 내 문제가 무엇인지에 대한 통찰력을 가지고 있습니까? c <- bodyString에서TCP 클라이언트가 작동하지 않습니다. golang

package main 

      import (
       "bufio" 
       "encoding/json" 
       "flag" 
       "fmt" 
       "io/ioutil" 
       "log" 
       "net" 
       "net/http" 
       "net/http/httputil" 
       "net/url" 
       "os" 
       "strconv" 

       auth "github.com/abbot/go-http-auth" 
      ) 

      type Configuration struct { 
       Server  string 
       Port   int64 
       UserName  string 
       Pwd   string 
       Realm   string 
       ProxyPort  int64 
       Edeserver  string 

      } 

      var (
       Config *Configuration 
       logp = flag.Bool("log", false, "enable logging") 
      ) 

      func ReadConfiguration() { 
       file, _ := os.Open("Config.json") 
       decoder := json.NewDecoder(file) 
       Config = &Configuration{} 
       err := decoder.Decode(&Config) 
       if err != nil { 
        fmt.Println("error:", err) 
       } 

      } 

      func Secret(user, realm string) string { 
       if user == Config.UserName { 
        // password is "hello" 
        return Config.Pwd 
       } 
       return "" 
      } 

      func reverseProxyTows(w http.ResponseWriter, authenticatedRequest *auth.AuthenticatedRequest) { 
       req := &authenticatedRequest.Request 

       if *logp { 
        log.Println(" Authenticated Username ", authenticatedRequest.Username) 
        log.Println(" Authenticated URL ", req.URL.RequestURI()) 
       } 

       destinationURL := fmt.Sprintf("http://%s:%d", Config.Server, Config.Port) 
       u, err := url.Parse(destinationURL) 
       if err != nil { 
        log.Fatal(err) 
       } 

       if *logp { 
        log.Println("reverse_proxy", u) 
       } 

       reverseProxy := httputil.NewSingleHostReverseProxy(u) 

       reverseProxy.ServeHTTP(w, req) 
      } 

      func openConnectionTotcp(edechannel chan string) { 
       conn, _ := net.Dial("tcp", Config.Edeserver) 
       text := <-edechannel 
       fmt.Fprintf(conn, text+"\n") 
       message, _ := bufio.NewReader(conn).ReadString('\n') 
       fmt.Print("Message from server: " + message) 
      } 


      func main() { 
       ReadConfiguration() 
       flag.Parse() 
       c := make(chan string) 
       go openConnectionTotcp(c) 

       fmt.Printf("Started proxy to destination server %v:%d and is listening on %d ", Config.Server, Config.Port, Config.ProxyPort) 

       authenticator := auth.NewBasicAuthenticator(Config.Realm, Secret) 
       http.HandleFunc("/", authenticator.Wrap(reverseProxyTows)) 
       http.HandleFunc("/tyrion/1", authenticator.Wrap(func(w http.ResponseWriter, authenticatedRequest *auth.AuthenticatedRequest) { 
        req := &authenticatedRequest.Request 
        bodyBytes, err2 := ioutil.ReadAll(req.Body) 
        if err2 != nil { 
         log.Fatal(err2) 
        } 
        bodyString := string(bodyBytes) 
        c <- bodyString 
        fmt.Fprintf(w, "success") 
       })) 
       http.ListenAndServe(":"+strconv.FormatInt(Config.ProxyPort, 10), nil) 
      } 
+1

"c <- bodyString"에서 실행 흐름이 차단 된 것처럼 보입니다. 채널에 대한 소비자가 없을 때 발생할 수 있습니다. 제발, 당신은 여기에 어떤 오류도 없다 "conn, _ : = net.Dial ("tcp ", Config.Edeserver)" –

+0

시작하려면, 당신은 'net.Dial' 또는 'ReadString', 당신은 tcp 연결을 닫지 않습니다. 여러개의 메시지를 읽으려면 버퍼 된 데이터를 가지고있는'bufio.Reader'를 버려야합니다. 'tcp.Dial'을 한 번 호출 한 후 goroutine을 종료하기 때문에 작동하더라도 첫 번째 http 요청 만 할 수 있습니다. – JimB

답변

0

귀하의 코드 실행 블록 아무것도 그 버퍼링 채널에서 읽는 것으로 보인다 없기 때문입니다. 이 행은 다른 루틴이 채널에서 읽을 때까지 실행을 일시 중지합니다.

+0

아니요 사실이 아닙니다 openConnectionTotcp에는 chan 인수가 있고 그 루틴은 루틴에서 읽습니다. "func openConnectionTotcp (edechannel chan string) { conn, _ : = net.Dial ("tcp ", Config.Edeserver) text : = "-eechannel" fmt.Fprintf (conn, text + "\ n") 메시지, _ : = bufio.NewReader (conn) .ReadString ('\ n') fmt.Print ("서버의 메시지 :"+ 메시지) } ''' – harry

+0

그 루틴은 하나의 메시지를 소비 한 다음 돌아 오면 채널에 대한 모든 쓰기가 영원히 차단됩니다. 또한 tcp.Dial에서 오류를 버리기 때문에 루틴에서 무슨 일이 일어나고 있는지 알 수 있습니다. – Adrian

+0

로컬 tcp 서버를 실행 중이고 tcp 서버 쪽에서 메시지를 볼 때 tcp 다이얼이 작동합니다. 컬링 요청을하는 클라이언트가 걸려있다. 어떻게 그 루틴이 하나의 메시지를 소비 한 다음 반환하겠습니까? 처음부터 채널을 닫지 않으므로 되돌아갑니다. – harry

관련 문제