--------------------------------------------------------------------------- Tizen native app으로 REST client app을 개발하고자
관련된 tutorial 링크 및 참고 사항들을 대충 정리 함...
- HTTP request/response 처리
- JSON parsing
- HTTP response 처리를 위한 Event-driven thread 사용
[HTTP transaction concept]
https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.appprogramming/html/guide/net/http_transaction.htmREST client app을 만드니... 기본적인 HTTP transaction에 대해서는 이해가 필요하겠지..
. HTTP transaction 에 대한 내용들
http://www.pearsonhighered.com/assets/hip/us/hip_us_pearsonhighered/samplechapter/0672324547.pdf
http://www.w3.org/2002/Talks/www2002-p3p/all.htm
. Chunked transfer
: 간단히 말하면 일반적인 http streaming transfer는 content를 response로 한번에 보내지만 chunked transfer는 content를 임의의 크기로 쪼개서 보냄. 이런 경우는 server측의 performance의 제약이나 전달되는 content가 실시간 생산되는 content의 경우(크기를 예측할 수 없음) 이런 방법을 사용.
: Tizen HTTP transfer default mode는 Non chunked transfer mode 이지만 일반적인 server에서는 chunked transfer 지원.
: http://en.wikipedia.org/wiki/Chunked_transfer_encoding
[HTTP request/response]
[HttpClient Sample Overview]
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.appprogramming/html/sample_descriptions/httpclient.htm
HTTP request를 전송하고 response의 body bytes 수를 표시하는 sample app.
tizen.org 를 대상으로 HTTPS request를 실행하므로 외부 network으로 연결에 문제가 없는 지 확인 필요. (proxy 같은)
[HTTP Client]
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.appprogramming/html/tutorials/net_tutorial/task_httpclient.htm
* HTTP request 시 http transaction을 asynchronous 하게 처리하기 위해 아래 IHttpTransactionEventListener 등록이 필요
Tizen::Net::Http::IHttpTransactionEventListener
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.apireference/classTizen_1_1Net_1_1Http_1_1IHttpTransactionEventListener.html
- OnTransactionAborted
- OnTransactionCertVerificationRequestedN
- OnTransactionCertVerificationRequiredN
- OnTransactionCompleted
- OnTransactionHeaderCompleted
- OnTransactionReadyToRead
- OnTransactionReadyToWrite
HTTP-GET 시나리오에서
no chunked transfer에서는 response header 전달 이후 전체 body가 전송되므로 다음과 같은 이벤트가 발생할 것이고
Client event Server
GET request >
HeaderCompleted event < response header
Completed event < response body
chunked transfer에서는 response header 전달 이후 body가 나눠서 오므로 다음과 같은 이벤트가 발생할 것이다.
Client event Server
GET request >
HeaderCompleted event < response header
ReadyToRead event < response body
ReadyToRead event < response body
ReadyToRead event < response body
Completed event < response body
HTTP-POST 시나리오는 아마도 이렇지 않을까? (해보지는 않음.)
Client event Server
POST request header >
ReadyToWrite event request data >
ReadyToWrite event request data >
ReadyToWrite event request data >
ReadyToWrite event request data >
Completed event < response body
[주의 및 참고]
* HTTP transfer를 app에서 사용 하려면 http privilege가 필요
. manifest.xml > privileges > http://tizen.org/privilege/http
* HttpSession의 copy constructor가 private 인 관계로 reference를 사용할 수 없음
* 일반적인 얘기겠지만 HttpSession의 instance를 http transaction 중 유지하지 않으면 listener 호출 중 crash 발생됨.
* Http request 시 특정 사용자 정보를 response callback에서 확인하려면 HttpTransaction의 SetUserObject()를 사용하라 HttpTransaction instance는 request, response시 모두 접근할 수 있음.
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.apireference/classTizen_1_1Net_1_1Http_1_1HttpTransaction.html#a8eff3be989218969838e76310cf99706
[HTTP programming guide]
나머지 항목들은 한번 보시라.
The most common uses of HTTP connectivity are the following:
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.appprogramming/html/guide/net/http_connectivity.htm- Making HTTP requests
- Receiving HTTP responses
- Using HTTP authentication
- Setting a Network Preference
- Using HTTP chunked mode
- Using HTTP cookies
- Uploading HTTP multipart entity data
- Using HTTPS
[JSON]
Introduction to JSON on Tizen
https://developer.tizen.org/documentation/articles/introduction-json-on-tizen
JSON Parser App
https://developer.tizen.org/dev-guide/2.2.0/?topic=%2Forg.tizen.native.appprogramming%2Fhtml%2Ftutorials%2Fweb_tutorial%2Ftask_jsonparserapp.htm
이 예제에서는 JSON data를 parsing해서 key, value list를 제공해 주는 예제다.
단지 JSON data인 string을 parsing해서 탐색 가능한 data structure로 제공해 준다는 의미만 있을 뿐.. 그 이상의 편의는 제공하지 않는다.
사용자가 json response를 직접 parsing 해서 원하는 value를 가져오거나 utility 함수를 만들어서 key에 맞는 value를 가져오도록 해야 할듯.
// Call JSON parser
IJsonValue* pJson = JsonParser::ParseN(buf);
__pJsonKeyList->RemoveAll(true);
__pValueList->RemoveAll(true);
TraverseFunction(pJson);
void
JsonForm::TraverseFunction(IJsonValue* pValue)
{
switch (pValue->GetType())
{
case JSON_TYPE_OBJECT:
{
JsonObject* pObject = reinterpret_cast< JsonObject* >(pValue);
IMapEnumeratorT<const String*, IJsonValue*>* pMapEnum = pObject->GetMapEnumeratorN();
while (pMapEnum->MoveNext() == E_SUCCESS)
{
...
case JSON_TYPE_STRING:
{
JsonString* pVal = reinterpret_cast< JsonString* >(pValue);
...
case JSON_TYPE_ARRAY:
{
JsonArray* pJsonArray = static_cast< JsonArray* >(pValue);
pJsonArray->GetCount();
IEnumeratorT<IJsonValue*>* pEnum = pJsonArray->GetEnumeratorN();
while (pEnum->MoveNext() == E_SUCCESS)
...
...
[Alternatives JSON parsers]
JsonCpp
: boost library 기반, library 생성을 위한 컴파일 필요
: http://jsoncpp.sourceforge.net/
cJSON
: simple, MIT license, 2013년이 최신 업데이트
: http://sourceforge.net/projects/cjson/
jsmn
: simple, MIT license, 아직 개발중으로 보임 2014년 최근까지 수정 내역 있음.
: https://bitbucket.org/zserge/jsmn/overview
다른 대안을 찾아 보니 위의 것들이 있었고 http://www.json.org/ 중간에 보면 각 언어에 맞는 json parser library들이 존재하니 알아서 취사 선택하면 될듯함.
간단하게 사용하고자 cJSON을 사용하였고 사실 Tizen에서 제공하는 JSON parser와 기능은 거의 동일하지만 c style로 api 사용 및 array 처리가 간단하다.
JsonCpp도 많이 사용하고 편리한 사용성의 api들을 제공하지만 boost library를 사용하므로 boost library의 cross compile이 필요하고 소스의 양도 좀 되서 그냥 패스함.
cJSON을 통해 parsing하면 cJSON* 이 리턴되고 이를 사용해서 key에 맞는 value들을 뽑아 내면 됨.
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains.
Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to
a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
/* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array)
cJSON *cJSON_GetArrayItem(cJSON *array,int item)
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)
cJSON* element = null;
element = cJSON_GetObjectItem(item, "peoples");
if(null != element)
{
int size = cJSON_GetArraySize(element);
for(int i = 0 ; i < size ; i++)
{
cJSON* child_element = cJSON_GetArrayItem(element, i);
AppLog("peoples (%d) = %s - %s", i, child_element->string, child_element->valuestring);
...
}
element = null;
}
[Thread]
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.appprogramming/html/guide/base/thread.htmTizen에서는 아래와 같은 두가지(Main thread 제외)의 thread model들이 사용할 수 있고 각각의 특색은 다음과 같음.
[Event-driven Thread]
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.apireference/classTizen_1_1Base_1_1Runtime_1_1EventDrivenThread.html
: Event-driven threads run based on events and they execute in a loop until they receive an event notification to terminate. Event-driven threads allow using asynchronous calls.
[Worker Thread]
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.apireference/classTizen_1_1Base_1_1Runtime_1_1Thread.html
: Worker threads run linearly; they only execute the main body of the thread and exit. Asynchronous calls cannot be used, since the thread does not run an event-loop.
주기적인 HTTP request/response를 처리하고자 할 경우 Event-driven thread를 사용해야 함. 단순 http request/reponse를 처리할 때는 상관없으나 loop을 사용할 경우 worker thread에서는 바로 error가 발생하는 것으로 보인다. 실제 tizen platform에서 처리하는 방법은 알 수 없으나 주기적으로 반복해야 하는 상황에서는 event driven thread를 사용하는게 필요 함.
사용상의 별 특이점은 없음. 예제대로 만들면 잘 돌아감.. ㅎ
댓글 없음:
댓글 쓰기