삽질하는플머

구글 네이티브 클라이언트 돌려보기

탐구생활/WEB 관련

구글 네이티브 클라이언트는 네이티브 바이너리를 크롬 웹브라우저 내에서 실행시키는 개념으로, 

처음 들었을 때는 "뭐야 이거! 액티브엑스의 크롬버전이잖아???!!!" 라고 현기증부터 났었는데... 

찬찬히 뜯어보고 나니 실행되는 바이너리의 권한을 보안이 강화된 샌드박스 내로 제한함으로서 

나름 지옥문이 열리지 않도록 이것저것 신경쓴 물건 되시겠다. 


OpenGL ES 2.0 기반의 3D 가속도 지원하고 크롬이 실행되는 환경이라면 윈도건 리눅스건 맥이건 가리지 않고 굴러간다. 

또다른 게임 플랫폼으로서 살펴볼만한 가치가 충분하다는 이야기. 


도대체 어떤 물건인지 궁금하니 일단 돌려보자. 

https://developers.google.com/native-client/?hl=ko


윈도에서 Cygwin과 Python 2.6.8을 이용해 테스트하다 실패했다. 역시 이런 거 할 때는 리눅스가 甲이다. 

파이썬 2.6.5 가 깔려있는 우분투 10.04 서버에서 다음과 같이 따라해보자. 

먼저 설치부터. 


$ wget http://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/nacl_sdk.zip

$ unzip nacl_sdk.zip

$ cd nacl_sdk

$ ./naclsdk list

... 뭐라뭐라뭐라...

$ ./naclsdk update

... 현재 안정화버전인 "후추_19" 가 내려온다. NaCL... 소금과 후추라니 네이밍센스 끝내주네!!



설치가 끝났으니 예제를 하나 골라잡이 돌려봐야지. 


$ cd pepper_19/examples/tumbler/

$ make

$ make RUN



5103 포트에 현재 작업 디렉토리에 대한 웹서버가 구동된다. 크롬으로 접속하기 전에 Native Client 설정을 켜주자. 

주소창에 about:flags 입력하고 네이티브 클라이언트 항목을 찾아 체크해준 뒤 제일 밑에 재시작 버튼을 눌러 크롬을 재구동한다. 




이제 우분투 서버의 5103 포트에 접속해 tumbler.html 을 클릭하자. 





오늘은 일단 여기까지. 




PHP 에서 Int64 숫자값 문제

탐구생활/WEB 관련
PHP의 최대 정수값은 다음 코드로 살펴볼 수 있다. 

echo PHP_INT_MAX;



이 값은 32비트에서는 2,147,483,647. 64비트에서는 9,223,372,036,854,775,807 이다. 하지만 윈도에서는 32비트건 64비트건 관계없이 2,147,483,647 이다. (참고링크 : http://www.pubbs.net/200902/php/3781-re-php-dev-casting-doubles-to-ints.html)
 
내 경우 게임 캐릭터의 사이버머니 또는 현금의 필드값은 BIGINT, 즉 Int64 형을 쓰고 있다. 비교에서 사용될 경우야 단순히 문자열로 간주하면 상관없지만, 이렇게 '돈'에 관련된 경우는 상황이 조금 다르다. 직접적으로 값을 박아넣는 것이 아니라 기존값에 대해 증가시키거나 차감시키는 방식으로 처리하는 '연산'이 필요하기 때문이다. 따라서 PHP의 정수값 한계는 문제가 된다. 

게다가 PHP는 큰 정수의 경우 자동으로 실수값으로 변환해 처리하게 된다. 정수 한계를 벗어나는 큰 수를 변수에 넣고 출력해보자.

$k = 703687441776631235523;

echo $k;
echo sprintf('%f', $k);



출력결과는

7.0368744177663E+20
703687441776631218176.000000



이처럼 입력값과 전혀 관계없는 부정확한 값이 찍히게 된다.

일단 떠오르는 해법은 두가지. 스토어드 프로시저를 써서 MySQL에서 현금값을 차감하는 함수를 만들고 이것을 호출하는 방법. 
두번째는 BCMath(http://kr2.php.net/bc), 또는 GMP(http://www.php.net/manual/en/book.gmp.php) 를 사용하는 방법.

GMP는 잘 모르겠고, BCMath의 경우는 우분투, 윈도용 WAMP, NAS 세군데 모두 번들되어있다. 따라서 이 녀석을 쓰자.

$m = bcadd("703687441776631235523", "1", 0);
echo $m . '<BR>';


 
출력결과는 다음과 같다.

703687441776631235524


 
bcadd 의 마지막 인자는 결과값에서 사용할 소수점 자릿수. 정수만 쓰려면 0을 준다. 
또는 bcscale() 함수로 전역적으로 설정할 수도 있다.

bcscale(0);
$m = bcadd("703687441776631235523", "1");
echo $m . '<BR>';


 
BCMath 에는 이 외에도 빼기, 나누기, 곱하기, 승수 처리함수가 내장되어있다. 두 숫자가 같은지 비교하는 bccomp 도 유용하다. 
이로서 DB에 들어있는 BIGINT 현금값을 문자열로 간주, BCMath로 비교후 차감한 뒤 그 결과값을 돌려줄 수 있게 되었다. 

xmlrpc-epi 로 만든 RPC 서버에서 압축전송된 요청 다루기

탐구생활/WEB 관련
델파이와 PHP 에서 XLMRPC 를 가지고 노는 이야기는 오래전에 위키에 끄적인 적이 있는데... 지금은 날아가버렸다. 
백업된 문서 찾아다 블로그에 정리해야겠다. (... 고 생각한지 벌써 일년이 훌쩍... ㅠㅠ) 

xmlrpc-epi 는 예전에 살펴본 php-xmlrpc 와 기능면에서 거의 같으면서도 C로 만들어진 확장이라 속도가 좀 더 빠르다. 
사용법도 비슷해서 include("xmlrpc.inc"); 를 include("xmlrpc_emu.inc"); 라고 끝에 "_emu" 만 붙여주면 된다. 
무엇보다 대부분의 PHP 배포판에 기본적으로 포함되어있다는 것이 장점이다. 심지어는 시놀로지의 NAS에도 들어있다. 
게다가 나는 팔랑귀이므로 뭐가 조금이라도 좋다고 하면 써봐야 직성이 풀린다. 

 다만 무슨 일인지 우분투 10.04에서는 빠져있는데, 아래와 같이 설치하고 아파치를 재구동하면 올라온다.  (예전에는 들어 있었는데...)

sudo apt-get install php5-xmlrpc



WAMP 에서는 트레이를 클릭하고 PHP -> PHP Extensions -> php_xmlrpc 확장을 선택하면 된다. 





xmlrpc

core library version xmlrpc-epi v. 0.51
php extension version 0.51
author Dan Libby
homepage http://xmlrpc-epi.sourceforge.net
open sourced by Epinions.com



http://xmlrpc-epi.sourceforge.net/ 에서 xmlrpc-epi-php-0.51.tar.gz 를 다운받아 압축을 풀고 util 디렉토리를 include 경로에 포함시키면 사용준비는 완료. 


 

PHP+MySQL+xmlrpc-epi 로 만든 XMLRPC 기반의 데이터 서버와 델파이로 정보를 주고 받는 중인데, DB값의 특성상 키와 값으로 쌍을 이루는 "구조체" 형식을 선호하다 보니 전송 데이터가 상당히 커지게 되었고, 이거 필드에서 제대로 써먹을 수 있을지 슬쩍 겁이나기 시작했다. 

일단 받는 정보부터 압축해보자. PHP.INI 를 다음과 같이 설정하고
 

zlib.output_compression = on
zlib.output_compression_level = 9 



zlib
........

DirectiveLocal ValueMaster Value
zlib.output_compression On On
zlib.output_compression_level 9 9
zlib.output_handler no value no value



RPC 함수 호출시 HTTP 헤더의  Accept-encoding 에 "gzip,deflate" 라고 적어주면 gzip으로 압축된 정보가 날아온다. deflate로 날아온 정보는 ZLib로 바로 풀리고 gzip의 경우는 
DelphiZLib 의 ZLibExGZ 유니트를 사용하면 되므로 일단 한 숨 돌렸는데...
저장하기 위해 서버로 보낼 정보도 만만치 않게 크기 때문에 마찬가지로 압축을 해주기로 하면서 고민이 시작된다.



HTTP 헤더의 Content-Encoding 에 deflate, 또는 gzip 을 적어주고 XML을 압축한 뒤 서버를 호출하니 다음과 같은 에러가 나온다. 

32700: parse error. not well formed. 
error occurred at line 1, column 1, byte index 0



데이터가 요사스러워 첫줄 첫번째 컬럼 제일 앞바이트부터 에러가 난다고 툴툴거리고 있다.
저 에러는 C확장 내부에서 내는 것으로서 한마디로 압축된 그대로 넘겨받았다는 이야기. 


흠... 설정에 output_xxx 만 있을 때 부터 알아봤어야 하는데... 들어오는 정보는 직접 풀어줘야하나보다. 


서버 객체가 정의된 xmlrpcs_emu.inc 파일의 177 라인을 살펴보니 전달된 HTTP_RAW_POST_DATA 를 날것 그대로 던져주고 있다. 
여기에 클라에서 전달받은 Content-encoding 값으로 압축여부를 판단해 압축을 풀어주는 코드를 추가해보자. 

    // public. service the xmlrpc request
    function service() {
       Header("Content-type: text/xml; Content-length: " . strlen($payload));
 
       global $HTTP_RAW_POST_DATA;
       $data=$HTTP_RAW_POST_DATA;
 

      // 데이터가 압축되어있는지 살핀다. 압축되어있다면 풀자. 
         if(isset($_SERVER['HTTP_CONTENT_ENCODING']))
             $content_encoding = str_replace('x-', '', $_SERVER['HTTP_CONTENT_ENCODING']);
         else
             $content_encoding = '';
 
         if ($content_encoding == 'gzip' && function_exists('gzinflate') && $degzdata = @gzinflate(substr($data, 10))) {
             //echo 'GZip decompress!';
             $data = $degzdata;
         } else
         if ($content_encoding == 'deflate' && function_exists('gzuncompress') && $degzdata = @gzuncompress($data)) {
             //echo 'Deflate decompress!';
             $data = $degzdata;
         }



        // call server
       echo xmlrpc_server_call_method($this->xmlrpc_server, $data, $this->dmap, 
                                      array(output_type => "xml", version => "xmlrpc", encoding => "UTF-8"));
    }



녹색으로 둘러친 부분이 추가한 내용이다. 이제 함수호출 정보를 gzip, 또는 deflate 로 압축해 던져도 제대로 반응하게 된다.  

XML은 텍스트로 된 정보이므로 압축률이 높다. 크기가 커질수록 효율은 더욱 좋아진다.
3천바이트 가량의 XML이 1/5인 600바이트 정도로 줄어들어 왔다갔다 하는 것을 보면 답답했던 속이 뻥~ 뚫릴 것이다. 



ps. php-xmlrpc 에는 압축 전송된 요청을 풀어주는 코드가 이미 들어있다.
     따라서 이 고민은 "똑같은 PHP에서 XMLRPC 사용인데 xmlrpc-epi 는 왜 안되는거야!!" 하는 사람에게만 유효하다. 



VCL for PHP 를 우분투 8.10 서버에 올려보자.

탐구생활/WEB 관련
VCL for PHP 는 PHP가 구동되는 곳이면 OS를 가리지 않고 동작한다. 뭐 당연한가??
아무튼 요새 잘 써먹고 있는 우분투 8.10에 이 물건을 올려보자.

우분투 서버는 8.10 버전이고 LAMP로 구성되어있으며 웹페이지 루트는 /var/www 이다.

Delphi for PHP로 만든 어플을 "배포마법사"를 써서 뽑아내 보면 어플 디렉토리 밑에 /vcl 이 생기고 여기에 VCL for PHP 중 필요한 파일들이 설치되는 구조이다. 그러나 어플리케이션마다 이렇게 /vcl 이 따라붙는다면 별로 바람직하지 않을 것이다. 구글신에게 빌어보니 다음과 같은 신탁을 내려주시네.

http://www.thecodecave.com/article366


일단 다운로드부터 받고



압축 풀고 /var/www 로 옮겨둔다.

# tar -xzf vcl_for_php2_1.tar.gz
# mv vcl /var/www/


웹페이지 루트에 vcl-bin 이라는 심볼릭 링크를 걸어준다.

# cd /var/www
# ln -s vcl vcl-bin


Delphi for PHP
에서 적당한 예제를 만들어주고 메뉴에서 Tools -> Deployment Wizard 를 선택해 배포할 PHP파일들을 뽑아낸다. 이 때 따라붙는 VCL은 신경쓰지 말고 배포 디렉토리에 생겨난 파일만 옮겨오면 된다.

새로 만든 예제를 /var/www/appls/test 에 올렸다고 예를 들면 이제 이 디렉토리로 가서 아까 풀어둔 vcl 디렉토리에 대한 심볼릭 링크를 걸어주자.

# cd /var/www/appls/test
# ln -s ../../vcl vcl


이제 접속해서 테스트 해 보면 짜잔~~ 아까 만들었던 예제가 우분투 서버에서도 잘 돌아가는 것을 확인할 수 있다. (컴퓨터에 그래픽용 어플이라고는 그림판밖에 없어서... 스샷은 다음 기회에...)


VCL for PHP

탐구생활/WEB 관련
작년쯤에 코드기어의 Delphi for PHP 발표회에 다녀왔던 기억이 난다.
사실 오래간만에 반가운 얼굴들이나 보러 갔던거고 발표회 자체는 뭐 그런게 있나보다 하고서 완전히 잊어먹고 있었는데...

KLDP에 흡혈양파님이 올려두신 글을 뒤늦게 읽어보게 되었고, Delphi for PHP에서 사용하는 VCL for PHP 가 오픈소스로 개발중이라는 놀라운 사실도 알게 되었다. 그것도 무려 LGPL로...

사실 윈도에서 돌아가는 게임을 만드는 나 같은 사람은, 깊은 우물에 갇혀 주위를 둘러보지 못하고 살아가곤 한다. 게다가 클라이언트 프로그램을 짜다가 서버를 맡고 있으니 더더욱 그러하다. 수많은 연장들이 널려있는 작업장에서 드릴로 뚫어야 할 구멍을 십자드라이버 하나 들고 잘났다고 하는 꼴이란... 그러다 cygwin 같은 물건을 만나면 문화적 충격을 받고 이렇게 블로그질이나 하는 것이고...

쉽게 말해 동생이 졸업논문 쓴다고 설문조사 웹페이지를 만들어달라고 하면? 액티브엑스부터 떠올리는 화상인 게지. 뭐 덕분에 생전 처음 PHP와 MySQL을 가지고 놀아봤지만...

아무튼 이 물건은 델파이의 VCL을 그 느낌 비슷하게 PHP로 완전히 바꿔놓은 녀석이다. 홈페이지는 여기고 예제는 여기에 있다. 폼도 있고 버튼도 있고 메뉴도 있다. 완전이 깜놀...

게임 운영 프로그램을 만들어야 할 때, 이거만한 해법이 또 있을까... 게다가 그 자체로 멋진 IDE인 Delphi for PHP의 가격은 미국 기준으로 $274.00. 우와~~ 멋진데~~~~ (그건 그렇고 만수횽아~ 환율 좀~~)

물론 국내가격은 좀 세다. 580.800원. 환율 문제도 있겠지만, 오래 전 터보델파이의 악몽이 떠오른다. 흑흑흑~~~

뭐 30일 트라이얼이 있으니 맛보는 것은 얼마든지 가능. 게다가 만들어진 프로그램은 PHP가 설치된 곳이면 OS를 가리지 않고 실행되니 이보다 더 좋을 수는 없을 듯...