Heroku는 호스팅 서비스입니다. 
http://www.heroku.com/

요즘은 호스팅 서비스가 참 많이 있는데요. 지원하는 방법도 틀리고, 지원 범위도 매우 다양합니다.
구글 앱엔진 같은 경우, Java와 Python을 통해 앱을 개발하고 구글 앱엔진서버에 올려서 서비스하는 방식이죠. 대신에 FTP 같은 것을 지원하지 않고, 한번에 배포를 하는 방식이며, Database는 우리가 일반적으로 쓰는 SQL형태(MySQL, Oracle 등)과는 다르게 BigTable이라는 접근제한(?)적인 DB를 제공합니다.
국내에서 서비스 하는 Cafe24 같은 경우는 그냥 ftp를 지원하고, Mysql계정을 주며, 직접 안에서 개발을 하고, Java같은 경우 개별 톰캣을 줘서 시작하고 끌 수 있는 형태로 호스팅을 하고 있죠.

Heroku도 구글앱엔진과 비슷한 형태로 서비스를 하고 있는데요. Heroku는 git를 이용해서 로컬에서 개발해놓은 것을 Heroku에 올립니다. 이 때 Procfile이라는 것을 같이 올리는데, 여기에 서비스 시작 명령어 같은 것이 있습니다. 그러면 올리자마자 해당 서비스가 돌아가게 됩니다.
Node.js에 대해서 검색해보다가 Node.js를 호스팅해주는 서비스라고 해서 알아봤는데, Java도 되고, 루비도 되고, 좋은 것 같네요. 근데, 용량을 늘리거나 다른 기능을 쓰려면 돈을 내야합니다. 하지만, 일부는 무료인 것 같습니다.

제가 Windows를 쓰고 있어서 이걸로 설명을......

공식사이트에 나와있는 Windows에서 시작하기 및 Node.js 시작하기 문서를 참조했습니다. 뭐 참조해서 했다기보다 그냥 그거 보고 따라한거에요~ 제 글보다 영어가 편하시면 이 아래의 글을 읽는 게 더편할 듯!
windows에서 시작하기 : http://devcenter.heroku.com/articles/windows 
node.js시작하기 : http://devcenter.heroku.com/articles/node-js


1. Heroku 설치

일단 Heroku 사이트에 가입하시구요. 공식사이트에서는 http://railsinstaller.org 에서 한번에 git와 ruby를 설치하는 것을 설명해놨네요.

Heroku설치는 gem을 이용해서 설치하면 됩니다.

gem install heroku



2. ssh key셋팅

git를 제가 잘 몰라서 제가 일단 이해한대로 작성을.....-_-
git에 접근하기 위해서는 그 해당 git에 권한이 있어야 하는데, 해당 git에 등록된 ssh key만이 접근이 가능합니다. 그래서 heroku에 공개키를 업로드해서 얘는 여기에 등록된 사용자 라는 것을 판단하는 것 같습니다.

일단 키를 생성해야 합니다.
git 설치하면 Git Bash프로그램이 생깁니다. 그걸 실행.
아래와 같이 명령어를 치면

ssh-keygen -t rsa



홈폴더/.ssh/id_rsa과 id_rsa.pub파일이 만들어집니다. 그럼 이제 이 pc에서는 git로 이 키가 등록된 곳은 clone이 가능하겠죠. 키를 추가하는 방법은 아래 명령어로 추가합니다.

heroku keys:add

 
키가 추가됐는지 보려면 그냥 heroku keys 치면 되고, 키를 지우려면 heroku remove mudchobo@MUDCHOBO-VAIO 이렇게 치면 되고, 뒤에 인제 없이 remove만 하면 다 날라가더라구요-_-


3. Node.js 코딩

보니까 socket.io와 expres framework를 지원하는 것 같더라구요. 둘 다 사용하는 예제로 한번 올려보겠습니다.
app.js, index.html, Procfile, package.json 파일을 만들어서 올립니다.
app.js파일은 실제 node.js코드파일이고, index.html은 node.js에서 내려주는 클라이언트 파일이며 Procfile은 heroku에서 사용하는 앱 실행명령어가 있는 파일이며, package.json은 현재 프로젝트에 대한 요약 및 어떤 버전에 의존하고 있는지 명세하고 있는 파일입니다.

app.js
var app = require('express').createServer()
,io = require('socket.io').listen(app);

// 여기서 포트는 지정할 수 없고 하나만 쓸 수 있음. 미리정해진 상수.
app.listen(process.env.PORT);
console.log("port = " + process.env.PORT);

app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});

io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});


index.html
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
  });
</script>


package.json 
{
"name": "node-example",
"version": "0.0.1",
"dependencies": {
"express": "2.2.0",
"socket.io": "0.8.2"
}
}


Procfile
web: node app.js


4. git로 커밋과 remote쪽인 heroku로 push

이제 이 폴더를 git로 새로 생성해서 커밋을 합니다.

git init
git add .
git commit -m "init" 

 
그리고 heroku의 새로운 프로젝트를 생성해야 합니다.
Heroku에서 얘기하는 Cedar stack이 아직도 뭔지 모르겠습니다. 근데, Java나 Ruby On Rails, Node.js를 사용하려면 이걸로 프로젝트를 생성해야하는 것 같습니다. 

heroku create --stack cedar helloworldnodejs(원하는 이름)

이거 하면 해당 git에 remote로 heroku라는 이름으로 추가가 됩니다. 저기 원하는 이름을 쓰지 않으면 랜덤으로 이름을 생성해서 만듭니다. 그리고 현재 heroku에서 존재하는 이름으로 생성해도 Name is already taken이라는 에러메세지가 뜹니다. 유니크하게 적어주면 됩니다.

이제 push하면 됩니다.
git push heroku master

현재 프로세스가 돌아가는지 보려면
heroku ps
또는 정확하게 앱을 찍어서
heroku ps --app helloworldnodejs(앱 명칭)


5. 앱이 잘 돌아가는지 확인

heroku의 앱 url은 앱이름.herokuapp.com 입니다.
http://helloworldnodejs.herokuapp.com/
여기 접속해서 console로 helloworld가 뜬다면 된 것이겠죠. 서버쪽 로그도 확인할 수 있는데, 서버로그는 ps명령어와 동일합니다.
heroku logs --app helloworldnodejs(앱 명칭)


PS. play! framework도 꽤 관심있었는데, 여기서 호스팅까지 해준다니 이번 기회에 한번 봐야겠네요. node.js를 이용해서 초간단 html5게임이나 한번 만들어봐야겠네요~!
 
Posted by 머드초보
,
 
일단 인증을 받기 위해서 애플리케이션을 등록해야합니다.
페이스북 developer페이지
http://www.facebook.com/#!/developers/apps.php

여기서 새 애플리케이션 셋업을 선택해서 애플리케이션을 등록해야합니다.
등록하고 나서 설정에서 Web Site탭에서
Site URL을 해당 "http://인증할 사이트주소/", Site Domain을 "인증할 사이트주소" 이렇게 설정합니다. 이렇게 안하니까 에러나더라구요-_-
저는 http://mudchobo.tomeii.com/ , mudchobo.tomeii.com 이렇게 셋팅했습니다.

그리고 이제 인증받을 페이지를 만듭니다.
index.html
[code]
<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script> 
        <script type="text/javascript">
            $(document).ready(function(){
                $("#btnAuth").click(function(){
                    window.location = "https://graph.facebook.com/oauth/authorize?client_id=126292714090241&redirect_uri=http://mudchobo.tomeii.com/test/facebook/callback.html&type=user_agent&display=popup&scope=publish_stream,create_event,rsvp_event,sms,offline_access";
                });
            });
        </script>
    </head>
    <body>
        <button type="button" id="btnAuth" name="btnAuth">인증받기</button>
    </body>
</html>
[/code]
뭐 간단한데, 인증버튼이 있는데, 인증 받으려고 해당 url로 갑니다. 이거 팝업으로 한다음에 인증받고 callback에서 다시 팝업->부모페이지로 전달해서 하는 방법도 있는데, 귀찮으니까 그냥 페이지로 넘기고 콜백으로 넘어갑시다-_-

인증url을 보면 client_id가 application_id입니다. 저는 이런 단어통일이 안되어서 몬가 삽질을 좀 했습니다. 왜 단어가 틀려-_-

그리고 rediret_uri는 인증받고 다시 돌아올 주소고, scope는 이 인증에 어디까지 권한을 주는것이냐 입니다. 저기에 있는 게 다인데, 글쓰기권한은 publish_stream하나면 되는 듯. 나머지는 몰라서 막 추가해봤음...ㅠㅠ

인증받으려고 하면 아래와 같은 화면이 뜹니다.
사용자 삽입 이미지
허가하기 누르면 이제 access_token을 가지고 callback url로 옵니다.
이제 이 access_token만 있으면 글쓰기를 하거나, 글을 가져올 수 있습니다.

콜백을 보면...
callback.html
[code]
<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script> 
        <script type="text/javascript">
            var url;
            var accessToken;
            var userId;
           
            $(document).ready(function(){
                url = new String(window.location);
                accessToken = url.substring(url.indexOf("#") + 14, url.indexOf("&"));
                var userId = accessToken.substring(43, 53);
               
                // 자신의 정보 가져오기
                $.getJSON("https://graph.facebook.com/me?access_token=" + accessToken + "&callback=?", result);
            });
           
            function result(data){
                userId = data.id;
               
                // 글쓰기 버튼 이벤트 추가
                $("#btnWrite").click(function(){
                    var data = $("#taWall").val();
                    if (data.length <= 0){
                        alert("글을 입력하세요!");
                        return;
                    }
                    var query = "use 'http://mudchobo.tomeii.com/test/facebook/facebook_wall_table.xml' as htmlpost;" +
                                    "select * from htmlpost where " +
                                    "url='https://graph.facebook.com/" + userId + "/feed' " +
                                    "and postdata='access_token=" + accessToken + "&message=" + encodeURIComponent(data) +"'" +
                                    "and xpath='//p'";
                    var url = "http://query.yahooapis.com/v1/public/yql?format=json&callback=?&q=" +
                        encodeURIComponent(query) + "&diagnostics=true";
                    $.getJSON(url, cbResult);
                });
            }
           
            function cbResult(data){
                alert("글쓰기 완료!" + data.query.results.postresult.p);
            }
        </script>
    </head>
    <body>
        <textarea id="taWall" name="taWall"></textarea>
        <button id="btnWrite" name="btnWrite">글쓰기</button>
    </body>
</html>
[/code]
accessToken을 url에서 가져오고, 자신의 정보를 access_token을 이용해서 가져옵니다.

그리고, 이제 문제는 글쓰기 부분인데요. 타도메인에 post요청을 할 수 없기 때문에 서버프록시를 이용해야합니다. 제가 가지고 있는 이 tomeii서버는 몬가 https를 요청하니 에러를 뿜는 것 같아-_- YQL이라는 것을 찾았습니다.
이거 좀 짱인데, 나중에 공부해봐야겠습니다.

일단 YQL에 포스트를 날릴 TABLE을 만들어야 하네요. YQL은 저도 잘 모르니 POST요청하는 거 그냥 찾아서 따라해봅니다-_- 아래 사이트 참조
http://www.wait-till-i.com/2009/11/16/using-yql-to-read-html-from-a-document-that-requires-post-data/

facebook_wall_table.xml
[code]
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd">
    <meta>
        <author>Mudchobo</author>
          <description>HTML pages that need post data</description>
          <sampleQuery>
              <![CDATA[
                select * from {table} where
                url='http://mudchobo.tomeii.com/test/facebook/test.php'
                and postdata="access_token=a&message=b" and xpath="//p"
            ]]>
        </sampleQuery>
          <documentationURL></documentationURL>
      </meta>
      <bindings>
        <select itemPath="" produces="XML">
            <urls>
                  <url>{url}</url>
            </urls>
            <inputs>
                  <key id="url" type="xs:string" required="true" paramType="variable"/>
                  <key id="postdata" type="xs:string" required="true" paramType="variable"/>
                <key id="xpath" type="xs:string" required="true" paramType="variable"/>
            </inputs>
            <execute>
                <![CDATA[
                      var myRequest = y.rest(url);
                      var data = myRequest.accept("text/html")
                        .contentType("application/x-www-form-urlencoded")
                        .post(postdata).response;
                    var xdata = y.xpath(data,xpath);
                    response.object = <postresult>{xdata}</postresult>;
                ]]>
            </execute>
        </select>
      </bindings>
</table>
[/code]
뭐 잘은 모르겠지만, inputs태그에서 postdata랑 url을 받고 여기서 처리를 하는 듯.
javascript같은게 있는데, 여기서 post어쩌구 함수를 호출해서 날리고 response객체 저장시켜놓으면 그걸 얻어올 수 있는 것 같음.

쿼리는 이렇게 날리네요.
[code]
use 'http://mudchobo.tomeii.com/test/facebook/facebook_wall_table.xml' as htmlpost;
select * from htmlpost where url='https://graph.facebook.com/자기페이스북아이디/feed' and postdata='access_token=access_token&message=메세지'and xpath='//p'
[/code]
저렇게 yql을 getJSON으로 날리면 데이터처리를 야후서버에서 하겠죠^^ 그리고 리턴값은 글을 작선한 뒤에 아이디를 받아옵니다.

ps1. YQL진짜 신기하네요-_- 저런식으로 하면 정의된 테이블에 의해서 처리를 한다음에 결과값을 실어서 주네요.

ps2. 예제주소는 여기에....
http://mudchobo.tomeii.com/test/facebook/

 
Posted by 머드초보
,
 
한번 만들어보려고 했는데요... 그냥 우연히 Canvas를 이용한 Coverflow 라이브러리가 있을 것 같아서 검색해보니 역시 있네요.
근데 얘좀 잘못 만들어진 듯-_- Canvas를 여러개 만들어놓고 돌리고 있네요-_- Canvas 하나면 될 듯한데...




사이트
http://jcoverflow.sourceforge.net/

사용법은 파일 다운로드해서 압축풀면, coverflow.js랑 coverflow.css넣고,
[code]<div id="coverflowHolder">
    <div id="__cvfl-coverflow-holder" style="display:none">
        <div id="__cvfl-coverflow">
            <div id="__cvfl-coverflow-wrapper"></div>
            <div id="smallerPreview"></div>
            <div id="__cvfl-coverflow-label"></div>
        </div>
    </div>
</div>[/code]
이런 div를 html에 넣고,
[code]Coverflow.init([리스트배열], {createLabel, onSelectCenter, refill});[/code]
이런식으로 호출해주면 되네요.
저기 리스트배열에는
[{src, labelObject}] 형식으로 src는 이미지 주소를 넣고, labelObject는 선택되었을 때 넣을 데이터를 넣으면 나중에 보여줄 때 편리하게 하는 것 같습니다.
그리고, 함수정의로 createLabel은 현재위치의 coverflow의 정보를 보여주기 위한 html을 리턴하는 함수입니다.
onSelectCenter는 선택된 것 클릭했을 때 액션이고,refill은 잘 모르겠습니다-_-

여러가지 기능이 더 있는 것 같은데, 몬가 문서정리가 하나도 안되어있는 것 같습니다.

아! 주의사항!
coverflow.js파일을 상단에 임포트하려고할 때 window.addEventListener가 undefined가 나와서, 로드가 완료된 뒤 처리하도록 바꿔야해요. 휠이 먹히도록 하는 부분인 듯 한데,
728~729줄을
[code]window.onload = function(){
    두줄넣기
}
[/code]
요렇게 처리!

이걸 응용해서만든! 가수별 앨범목록!
http://mudchobo.tomeii.com/jcoverflow/


안드로이드에서도 잘 되네요. 근데, 약간 느리고, 문제가 있긴 하지만, 일단 잘됩니다(응?)...
사용자 삽입 이미지

 
Posted by 머드초보
,
 
HTML5에서 WebSocket이라는 것을 지원하는데, 보면 그냥 우리가 일반적으로 쓰는 TCP형태의 소켓이 아니라 http와 같이 ws라는 프로토콜을 이용해서 통신하는 것 같습니다.

일단 pywebsocket사이트입니다.
http://code.google.com/p/pywebsocket/
이곳에서 0.5버전이 있는데, 그것을 받습니다.

설치하고 삽질해보려면 python이 필요합니다.
http://www.python.org/download/
파이썬을 잘 몰라서 그런데, 왜 버전이 두개로 나눠져있죠?-_- 2.6.5랑 3.1.2로 2.x버전과 3.x버전이 나눠서 그것도 2.x대 버전이 지속적으로 업데이트를 하고 있어요... 궁금하네.
일단 저는 2.6.5를 설치했습니다.
그리고 파이썬을 path에 잡아줍니다. 어디서든 실행해야하거든요.
Windows7기준으로 제어판 -> 시스템 -> 고급시스템설정 -> 환경변수에 있는 path에 python실행 경로를 추가하면 됩니다.

설치는 readme파일에 나온 것 처럼 그냥 build하고 install하면 된다는....
python setup.py build
하면 module파일들이 생성되고,
python setup.py install
하면 파이썬에 모듈을 설치하는 듯.

아...일단 이 모듈을 아파치와 연동해서 사용하는 방법이 있구요. 혼자서 테스트하며 띄울 수 있는 방법이 있네요. 일단 그냥 테스트해볼꺼니까 standalone모드로...

src/mod_pywebsocket폴더에 가면 standalone.py파일이 있는데, 실행하면 됩니다.
python standalon.py -w ../example/
상위에 있는 example폴더를 소켓에 올리는데, 파일 네이밍으로 소켓url을 정하게 되는 것 같습니다(?).
example에 echo_wsh.py파일이 있는데, ws://localhost/echo 로 요청하면 되더라구요.
거기에 있는 echo_client.py는 뭐하는 놈인지 모르겠네요ㅠㅠ
어쨌든 이제 브라우저코드를....

[code]
<!doctype html>
<html>
    <head>
        <meta charset="EUC-KR">
        <title>WebSocket Echo</title>
        <script type="text/javascript" src="jquery-1.4.2.min.js"></script>
        <script>
            var ws;
            $(document).ready(function(){
                if ("WebSocket" in window){
                    ws = new WebSocket("ws://localhost/echo");
                    ws.onopen = function(){
                        ws.send("message to send");
                    }
                    ws.onmessage = function(e){
                        $("#result").append(e.data + "<br />");
                    }
                    ws.onclose = function(){
                        // close
                    }
                }
               
                $("#btnConfirm").click(function(){
                    if (!ws)
                        return;
                    ws.send($("#textMessage").val());
                });
                $("#textMessage").keyup(function(e){
                    if (e.keyCode == 13){
                        if (!ws)
                            return;
                        ws.send($(this).val());
                        $(this).val("");
                    }
                });
            });
        </script>
      </head>
    <body>
        <input type="text" id="textMessage" />
        <input type="button" id="btnConfirm" value="전송"/>
        <div id="result"></div>
      </body>
</html>
[/code]
쉬운 코딩은 역시 jquery...
WebSocket을 만들고, send로 보내고, onmessage이벤트로 수신받습니다. 아직 크롬에서 밖에 안됨-_-

예제 사이트도 있습니다.
http://code.google.com/p/websocket-sample/
다른 건 안보고 채팅예제만 좀 봤는데, tcp소켓처럼 하는 방식은 아니더군요.
보니까 서버에 파일을 하나 생성해서 한쪽에서 메세지를 던지면 파일에 쓰고, 다른 한쪽은 계속 그 파일을 주시하다가 변경되었으면 그걸 이용해서 연결된 쪽에 메세지를 전달하는 형태로 구현이 되어있습니다.


 
Posted by 머드초보
,
 
아...좀 문제가 발생할 것 같기도 하지만-_- 괜찮을꺼에요-_-
일단 플러그인을 하나 만들었는데요. 조금 문제가 많습니다만, 기본적인 기능은 다 되는.....-_-
크롬플러그인의 특징은 백그라운드에서 어떤 작업을 계속적으로 실행할 수 있는 특징이 있습니다. 그래서 html + Javascript의 조합을 통해서도 RSS Reader기를 만들 수 있죠. 게다가 html5문법인 audio와 video 등의 태그를 사용하여 백그라운드에서 실행하는 플레이어를 만들 수 있습니다.
html5에서 지원하는 localStorage도 지원을 해서 영속성이 있는 데이터를 저장할 수 있어요.
그 외에 html5에서 지원하는 canvas도 되구요. 번역기와 같이 현재 열려있는 페이지에 플러그인을 이용해서 번역도 되게 가능하구요. 또한 모질라처럼 NPAPI인지뭔지도 지원하는 것 같은데, DLL파일을 사용할 수 있게 하는 것 같아요. ie탭을 보면 dll파일을 이용해서 하는 것 같네요.

그래서 백그라운드에서 돌아가는 뮤직비디오 플레이어를 만들어 봤습니다.
소리바다에는 뮤직비디오를 퍼갈 수 있는 뮤비위젯이 있습니다. 아마 외부에서 재생이 되게 계약이 된 것으로 알고 있습니다. 그래서 이 뮤비위젯을 이용해 크롬플러그인에서 뮤비들을 localStorage에 저장해놓고 백그라운드에서 재생하는 플레이어를 만드는 것이죠.
뮤비위젯 사이트인데, 이것을 yahoo pipe를 이용해서 html파싱하면 해당 페이지의 뮤직비디오 데이터를 가져올 수 있어요-_- 그 데이터를 가져와서 플러그인에서 재생시키면 됩니다.

이 플러그인은 최신 뮤직비디오를 쉽게 감상할 수 있고, 해당 뮤직비디오만들 모아서 백그라운드 플레이어에서 재생도 할 수 있는 플러그인입니다.
invalid-file

플러그인 설치 파일. 크롬 4.0beta사용자만 가능해요~

사용자 삽입 이미지

우선 크롬플러그인 구조가 백그라운드.html파일이 있고, 크롬플러그인 아이콘을 클릭했을 때 popup.html을 띄워서 컨트롤하는 페이지 2개를 사용할 수 있어요. 이 2개의 페이지는 서로간의 통신이 가능합니다.
[code]var bp = chrome.extension.getBackgroundPage();[/code]
이것은 bp객체를 통해서 백그라운드의 있는 함수같은 것을 호출할 수 있어요.

또한 html + javascript기반이기 때문에 기존에 사용하는 jquery 등의 프레임워크도 사용할 수 있어요. 저도 이것때문에 더욱 빨리 개발한 것 같네요. 역시 jquery가 짱인 것 같아요.

그리고, flash없이 video나 audio파일을 재생할 수 있는 것이 매력적이군요.
video태그는 매우간결한데요.
[code]<video id="video" src="동영상주소"></video>[/code]
이런식으로 해주면 돼요. 그리고 javascript로 컨트롤하려면 여러 함수가 지원됩니다.
그냥 videoid.play()하면 해당 src로 재생합니다.
src을 바꾸려면,
[code]videoid.src = "video주소";
videoid.load();[/code]
형태로 로드해주면 되고, 일시정지하려면 video.pause()인데, 정지함수는 없는 것 같아요. stop하니까 안먹히더라구요-_-

localStorage도 좋은 게 그냥 쿠키같이 서버에서 컨트롤하는 데이터가 아니라 클라이언트 단에서 저장할 수 있어서 좋습니다. 하지만, flash에서 제공하는 SharedObject보다 좀 안 좋은 게 배열을 저장 못합니다-_- object는 저장하는 듯 하는데, array를 저장하려면 json으로 변경해서 저장해야합니다.
localStorage를 사용하기 위해서는 데이터 가져올 때는 getItem, 저장할 때는 setItem, 모두 제거할 때에는 clear()의 함수로 사용합니다.
[code]localStorage.getItem("데이터명");
localStorage.setItem("데이터명", 데이터);
localStorage.clear();
[/code]
크롬 플러그인에서 배열을 저장하기위해서는 json으로 변경할 것이 필요한데, JSON관련된 라이브러리를 제공하더라구요. 스트링화 하고, 파싱하는 함수를 사용하면 됩니다.
[code]localStorage.setItem("저장배열명", JSON.stringify(array));
JSON.parse(localStorage.getItem("저장배열명"));[/code]

나중에 시간되면 크롬용 MP3Player도 만들어봐야겠어요. NPAPI를 제공하는 것 같아 로컬파일 접근도 되는 것 같아요(확실하진 않지만....-_-).
 
Posted by 머드초보
,