Skip to content
isdnetworks
Go back

중계하면서 다듬었더니 안 맞았다

인벤토리 화면을 맡았다. 서버에서 받은 아이템 목록을 Cocos2d-x 쪽 구조체에 담아 화면에 뿌린다. 사용할 때 그 값을 다시 서버로 보낸다.

구매가 계속 실패했고 서버는 그런 아이템이 없다고 답했다.

Table of contents

Open Table of contents

증상 — 화면을 맞추려다 통신이 깨졌다

받은 목록을 저장할 때 이렇게 했다.

std::string code = json["item_code"].asString();
// 앞뒤 공백을 없애고 대문자로 맞춘다
code = trim(code);
std::transform(code.begin(), code.end(), code.begin(), ::toupper);
item.code = code;

wp_001 처럼 뒤에 공백이 붙은 값이 섞여 있어서 정리한 것이었다. 화면에 찍을 때 줄이 어긋나 보였기 때문이다.

문제는 이 값을 그대로 서버에 돌려준다는 것이다.

보낸 값: WP_001
서버 기대: wp_001

서버는 iBatis 로 조회한 그 문자열을 키로 다시 찾는다. 자기가 준 것과 정확히 같아야 한다. toupper 로 대소문자를 바꾼 순간 다른 값이 됐다.

하나씩 빼 보며 좁혔다

전부 실패하는 것이 아니라 일부만 실패했다. 원래 소문자였거나 공백이 없던 값은 그냥 됐다. 그래서 서버 쪽을 먼저 의심했다.

들어온 값과 나가는 값을 같이 찍어 봤다.

CCLOG("recv=[%s] send=[%s]", item.raw["item_code"].asCString(), code.c_str());
recv=[wp_001 ] send=[WP_001]

한 줄로 드러났다. CCLOGrecvsend 를 나란히 놓지 않았으면 서버 쪽을 계속 의심했을 것이다. 값이 어디서 바뀌는지 모를 때는 들어온 지점과 나가는 지점을 같이 찍는 것이 빨랐다.

다듬는 코드를 한 줄씩 지우고 ndk-build 로 다시 올려 봤다. 공백 제거만 빼니 절반이 됐고 대문자 변환까지 빼니 전부 됐다.

JNI 로 넘어가는 경로도 함께 봤다. Java 쪽에서 String.trim() 이 한 번 더 걸려 있어 두 군데에서 값이 바뀌고 있었다.

표시용과 전송용을 나눴다

고친 방향은 원본을 손대지 않는 것이었다.

item.code    = json["item_code"].asString();   // 원본 그대로
item.display = trim(item.code);                 // 화면용

화면에는 display 를 쓰고 서버로는 code 를 보낸다. 정리가 필요했던 것은 맞다. 다만 정리한 값이 원본을 덮으면 안 됐다. JavaString.trim() 도 없앴다. 두 군데에서 고치면 어디서 바뀌었는지 찾기 어렵다.

같은 문제가 다른 데서도 있었다. 응답에서 아는 필드만 골라 구조체에 넣고 나머지는 버리고 있었다.

struct Item {
    std::string code;
    std::string name;
    int         price;
};

서버가 나중에 필드를 하나 더 보내기 시작하면 그건 버려진다. 그 필드를 같이 돌려줘야 하는 규칙이 생기면 클라이언트를 고쳐야 한다. 그래서 Item 에 원본 응답을 통째로 들고 있게 했다.

struct Item {
    std::string code;
    std::string name;
    int         price;
    Json::Value raw;     // 받은 것 전부
};

돌려보낼 때는 raw 에서 필요한 것을 꺼낸다. 내가 모르는 필드도 손실 없이 왕복한다.

가격에서도 같은 일이 있었다. 서버가 "price": "12000" 을 문자열로 주는데 정수로 읽고 정수로 보냈다.

받은 값: "012000"
보낸 값: 12000

어떤 값은 앞에 0이 붙어 있었고 그게 사라졌다. 형식과 값이 둘 다 달라진 것이다. 숫자로 계산할 일이 있으면 따로 변환해서 쓰고 돌려보낼 때는 받은 문자열을 쓴다.

판단 기준 — 손대도 되는 값과 아닌 값

세 부류로 나눠 봤다.

손대도 되나
화면에 보이기만 하는 것자유롭게
서버로 돌아가는 것손대지 않음
계산에 쓰는 것사본을 만들어 계산

이렇게 나누고 나니 어디를 고쳐야 할지 찾기 쉬웠다. 돌아가는 값에 변형이 들어간 자리를 찾으면 된다.

정리


Share this post on:

Previous Post
앱이 조금씩 죽어 갔다
Next Post
어떤 기기에서만 죽었다