본문 바로가기
Server

8. 로그인(2)

by Doromi 2018. 1. 11.
728x90
반응형

4-2-2. URL Parser

 

URL 부분을 우리가 원하는 요청에 대해서 지정된 API를 실행하도록 분류하는 기능을 한다.

mon_http.erl의 handle 함수를 다음과 같이 수정하여 실제로 Api,What,Opt 값을 얻어올 것이다.

handle(Req, State) ->
{Api, Req1} = cowboy_req:binding(api, Req),
{What, Req2} = cowboy_req:binding(what, Req1),
{Opt, Req3} = cowboy_req:binding(opt, Req2),

io:format("api=~p, what=~p, opt=~p ~n",[Api, What, Opt]),

{ok, Req4} = cowboy_req:reply(200, [
{<<"content-type">>, <<"text/plain">>}
], <<"{\"result\":\"Hello world!\"}">>, Req3),
{ok,Req4, State}.

 

cowboy_req의 binding 함수를 이용해서, router에서 설정한 값을 가져오고 해당값이 정확한 지 실제로 값을 출력해보는 코드를 추가하였다.

항상 얼랭 쉘 창이 있으면 닫고 다시 컴파일 하고 실행했는데 이를 얼랭 쉘을 그대로 두고도 컴파일 되도록

얼랭의 Dynamic Code Loading 기능을 이용하겠다.

 

4-2-3. Dynamic Code Loading

 

프로그램을 실행 중인 상태로 코드를 컴파일하고, 바로 프로그램에 적용할 수 있는 기능

이 기능을 사용하면 실제 서버의 운영중에도 서비스의 중단없이 실시간 업데이트 가능

 

코드를 서버에서 컴파일하기 싫을 때에는 컴파일 된 beam 파일만 가져다가 업데이트 하면 편리하다.

직접 얼랭의 컴파일 관련 모듈을 이용해서 Code Reloading Module을 만들어 보겠다.

 

src 디렉토리에 Module 이름은 mon_reloader로 mon_reloader.erl파일을 추가

 

우선 현재 서버에 로딩된 모든 파을을 검사해서 모듈이 변경되었는지를 판단하는 함수를 만들거다.

이름은 check

현재 서버에 로딩된 모든 파일은 얼랭 쉘에서 code:all_load()라는 함수를 실행하면 알 수 있다.

 

자동적으로 진행되어야 하기 때문에 프로세스 형태로 계속 떠 있으면서, 특정 한 시간 단위로 체크하는 기능이 필요

 

mon_reloader.erl 파일에 -author("") 뒤에 추가한다.

-include_lib("kernel/include/file.hrl").

%% API
-export([start/0, loop/1, reload/1]).

start() ->
Pid = spawn(mon_reloader, loop, [erlang:localtime()]),
timer:send_interval(timer:seconds(1), Pid, check).

loop(From) ->
receive
check ->
To = erlang:localtime(),
[check(From, To, Module, Filename)
|| {Module, Filename} <- code:all_loaded(), is_list(Filename)],
loop(To);
update ->
?MODULE:loop(From);
Other ->
io:format("~p~n",[Other]),
loop(From)
end.

check(From, To, Module, Filename) ->
case file:read_file_info(Filename) of
{ok, #file_info{mtime=MTime}} when MTime >= From, MTime < To ->
reload(Module);
_ ->
pass
end.

reload(Module) ->
io:format("Reloading ~p ...", [Module]),
code:purge(Module),
code:load_file(Module),
io:format(" ok. ~n").

spawn()함수는 프로세스를 생성하는 함수

loop()함수의 receive 부분이 프로세스의 동작을 의미

check()함수는 모듈 beam 파일을 읽고 변경 시간을 계산해서 reload() 함수를 실행하는 역할

reload()에서는 code:purge(Module)을 이용해서 모듈을 내리고, code:load_file(Module)을 실행해서 새로운 모듈을 로딩

 

mon_app.erl파일 수정

code reloader를 실행하는 mon_reloader:start() 추가해야 한다. 나중에 더 수정할 것들이 있으니 최종으로 마지막에 올리려고 한다.

 

mon_reloader.erl 수정

 

4-2-4. /login, /join

 

이제 바인딩한 값을 가지고 따로따로 함수를 분리해보겠다.

/login과 /join 그리고 /hello/world 요청이 왔을 때 각각 다르게 동작하도록

 

 

인자값을 4개를 받는 handle(Api,What,Opt,Req3) 함수를 추가하였다.

이제 요청한 값에 따라서 각각 다른 result 값을 받는다.

 

 

 

 

 

 

 

 

 

 

 

함수형 언어에서는 흔히 if else 구문을 사용하지 않는다.

함수를 이용해 패턴 매칭 형식으로 코드를 작성하는 것이 얼랭의 방식이다.

패턴이 여러 개 있을 경우에는 함수의 끝에 세미클론(;)을 붙이고, 마지막 부분에만 마침표(.)을 붙인다.

 

 

 

데이터 읽어오는 부분 23라인에 추가

cowboy_req:body_qs()는 HTTP Body 값을 읽어온다.

handle/4의 4번째 인자값도 data로 변경

 

/login을 처리하는 코드 추가

data에서 id와 password 값을 읽어오는 부분

proplists:get_value에서 첫번째 값은 key

두번째 값은 Data

Data중에서 key가 id인 값을 가져오라는 뜻

 

 

 

 

 

이렇게 받은 값을 id,password에 넣고 case 구문으로 패턴매칭 해서 id와 password 값을 비교

데이터 값을 전송할 때는 curl에 -d 옵션 이용

 

 

 

이제 회원가입 기능을 만들어야 한다.

필수적으로 아이디, 패스워드 데이터를 어딘가에 저장해야 할 필요성이 있다.

얼랭에서 데이터를 저장하는 방법은 매우 많지만 우리가 사용해 볼 것은 ETS와 Dets 모듈이다.

 

다음 글에서 이어서 공부해 보겠다.

728x90
반응형

'Server' 카테고리의 다른 글

10. 데이터베이스(1)  (0) 2018.01.12
9. 로그인(3)  (0) 2018.01.11
7. 로그인(1)  (0) 2018.01.10
6.기본 모바일 서버 만들기(2)  (0) 2018.01.10
5.기본 모바일 서버 만들기(1)  (0) 2018.01.07