2017-12-29 14 views
0

그래서 거래가 있습니다 : 저는 거대한 시스템 (PHP)을 몇 년 동안 사용해 왔으며 이제는 golang 스크립트에 대한 많은 작업을 포기하기로 결정했습니다. .GoLang WebServer가 Json Response의 param 구조체에 대한 설명을 보냅니다.

지금까지 몇 가지 PHP 스크립트를 go 버전으로 복제했습니다. 그런 다음 어느 옵션이 더 나은지 벤치마킹 할 수 있습니다 (확인, 이동 속도는 더 빠릅니다.하지만 컬 또는 소켓을 comunication해야하므로 여전히 가치가 있는지 확인해야합니다).

스크립트 중 하나는 임의의 코드를 생성하고,이 새로운 코드가 이미 사용 중인지 (mysql db에서) 확인하고, 그렇지 않으면 새 코드를 기록한 다음 다시 사용하십시오. 재귀 호출은 독점 코드를 찾을 때까지 다시 작동하십시오. 아주 간단한 것.

나는 이미 PHP에서이 코드 생성기를 가지고 있으므로 json params와 함께 http/post로 호출되도록 새로운 코드 작성기를 작성했습니다. 사용하여 리눅스 터미널, 나는

curl -H [headers] -d [jsondata] [host] 

로 전화를 내가

{"locator" : "XXXXXX"} 

후 아주 간단한 JSON을 다시 얻을, 나는 각각에 걸린 시간 스크립트를 호출하고 확인하는 간단한 PHP 스크립트를 작성 완료, 뭔가 같은 :

<?php 
public function indexAction() 
    { 
    $phpTime = $endPHP = $startPHP = 
    $goTime = $endGO = $startGO = 0; 

// my standard function already in use 


    ob_start(); 

    $startPHP = microtime(true); 
    $MyCodeLocator = $this->container->get('MyCodeLocator')->Generate(22, 5); 
    $endPHP = microtime(true); 

    ob_end_clean(); 


    sleep(1); 
    // Lets call using curl 
    $data = array("comon" => "22", "lenght" => "5"); 
    $data_string = json_encode($data); 

    ob_start(); 
    $startGO = microtime(true); 



    $ch = curl_init('http://localhost:8888/dev/fibootkt/MyCodeGenerator'); 
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Content-Type: application/json', 
      'Content-Length: ' . strlen($data_string)) 
    ); 

    $result = curl_exec($ch); 
    curl_close($ch); 
    $endGO = microtime(true); 
    ob_end_clean(); 

    $result_rr = json_decode($result); 

    // tst just echo the variable in a nice way, second parameter means no kill execution 
    tst($result, 1); // HERE IS MY PROBLEM, please read below 
    tst($result_rr, 1); // IT SHOW NULL 

    sleep(1); 

// just to have params for comparision, always try by shell script 
    ob_start(); 
    $startShell = microtime(true);; 

    $exec = "curl -H \"Content-Type: application/json\" -d '{\"comon\":\"22\"}' http://localhost:8888/dev/fibootkt/MyCodeGenerator"; 
    $output = shell_exec($exec); 
    $endShell = microtime(true); 
    ob_end_clean(); 

    tst(json_decode($output),1); // here show a stdclass with correct value 
    tst($output,1); // here shows a json typed string ready to be converted 

    // and here it is just for show the execution time ... 
    $phpTime = $endPHP - $startPHP; 
    $goTime = $endGO - $startGO ; 
    $shellTime = $endShell - $startShell; 

    tst("php " . $phpTime, 1); 
    tst("curl ". $goTime, 1); 
    tst("shell " . $shellTime, 1); 

내가 GO의 결과를 얻을 : 쉘 스크립트 작성자 :

,
{"locator" : "DPEWX22"} 

그래서이 코드는 stdobj로 꽤 쉽습니다.

그러나 말풍선을 사용하면 작업이 빨라집니다! 그래서 그것을 사용하고 싶습니다. 는하지만, 컬 요청은 같은 응답 :

{"Value":"string","Type":{},"Offset":26,"Struct":"CodeLocatorParams","Field":"lenght"} 
{"locator":"DPEWX22"} 

을 그리고 그것을 디코딩 할 때, 나는 결과로 널을 얻을!

CodeLocatorParams 그래서

아래 표와 같은 내가 포스트 PARAMS를 얻기 위해 이동에서 사용하는 구조체 유형, 여기 내 질문은 : GO이를 반환하는 이유는 무엇입니까? 그것을 피하는 방법.

나는 params를 사용하지 않고 유사한 json (그러나이 경우 qrcode 이미지 경로)에 응답하는 유사한 유사한 go 스크립트를 가지고 있으며 정상적으로 작동합니다!

내 이동 기능 :

type CodeLocatorParams struct { 
    Comon string `json:"comon"` 
    Lenght int `json:"lenght"` 
} 

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


    data, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) 
    if err != nil { 
     fmt.Println(err) 
     panic(err) 

    } 
    if err := r.Body.Close(); err != nil { 
     panic(err) 
    } 

// retrieve post data and set it to params which is CodeLocatorParams type 
    var params CodeLocatorParams 
    if err := json.Unmarshal(data, &params); err != nil { 
     w.Header().Set("Content-Type", "application/json; charset=UTF-8") 
     w.WriteHeader(422) // unprocessable entity 
     if err := json.NewEncoder(w).Encode(err); err != nil { 
      fmt.Println(err) 
      panic(err) 
     } 
    } 





    var result struct{ 
     Locator string `json:"locator"` 
    } 
// here actually comes the func that generates random code and return it as string, but for now, just set it static 
    result.Locator = "DPEWX22" 

    w.Header().Set("Content-Type", "application/json; charset=UTF-8") 
    json.NewEncoder(w).Encode(result) 


} 

답변

1

들어오는 JSON을 구문 분석 오류가 있습니다. 이 오류는 응답에 {"Value":"string","Type":{},"Offset":26,"Struct":"CodeLocatorParams","Field":"lenght"}으로 기록됩니다. 핸들러는 계속 실행하고 일반 응답 {"locator":"DPEWX22"}을 작성합니다.

여기에 무엇을 해결하는 방법은 다음과 같습니다

  • 오류 응답을 작성 후, 핸들러에서 돌아갑니다.
  • 입력 JSON은 문자열 값으로 길이가 있습니다. struct 필드를 int에서 string으로 변경하거나 입력을 수정하여 정수를 전달하십시오.
+0

yeap! lenght를 정수로 사용하면 문제가 해결됩니다! Cant는 그것이 매우 단순했다라고 생각한다! !! 고마워요 @ cerise 많이! –

+0

나는 혼자 깨닫지 못했다. 그것은 오류 경고였다. 나는 그것이 어떤 종류의 머리글이 될 수 있다고 생각했다. –

+0

@DiegoFavero 그건'json.NewEncoder (w) .Encode (err)'의 출력이다. JSON으로 오류를 인코딩하는 일은 거의 불가능합니다. err.Error()를 인코딩하는 것이 더 좋습니다. 구현 세부 사항이 클라이언트에 누설되므로 이상적이지 않습니다. 아마도 "JSON 구문 분석 오류"가 여기에서 최고의 선택 일 것입니다. –