websocket 연결을 수신하는 ws_handler가 있습니다.Cowboy Websocket 처리기에서 상태를 업데이트하면 자동으로 충돌이 발생하거나 무시됩니다.
이 프로세스는 로그인 할 때 <<"h
으로 시작하는 입력을 기다립니다.
는 그러므로 기본 웹 소켓 상태 (현재 PID에 대한 참조 스폰) 플레이어 프로세스 ID, 및 발신 메세지 '< < "turn1">>
websocket_handle({text, <<"h", Name/binary>>}, State) ->
{ok, PID} = player:go(self(), <<"profiledata", Name/binary>>),
erlang:start_timer(1000, self(), <<"Hello!">>),
{reply, {text, <<"You joined, ", Name/binary>>}, {State, PID, <<"turn1">>}};
I 절약 이 별도의 플레이어 프로세스에서 데이터 흐름을 제어하려면 내 websocket 처리기에서 메시지를 검색하여 Outbox
요소를 통해 클라이언트에 전달해야합니다.
websocket_info(myscreenupdate, State = {St,P, _}) ->
{reply, {text, <<"My screen update">>}, {St, P, <<"turn2">>}};
:
websocket_handle({text, <<"myscreen">>}, S = {_, P, _}) ->
gen_server:call(P, myscreen),
{ok, S};
및 player.erl에서
,handle_call(myscreen, _, {WS, Profile, Cab}) ->
gen_server:cast(WS, myscreenupdate),
{reply, ok, {WS, Profile, Cab}};
돌아 가기 ws_handler에서 나는이 전화를받을 것으로 예상 :
그래서 나는 수동으로 메시지를 트리거하기 위해이에 추가
그러나 내 브라우저에서 출력되는 websocket은대신에 turn1
을 계속 인쇄합니다..
gen_server:call
을 player.erl
에 시도했는데 시간 초과 오류가 발생합니다. 나는 ws_handler
에 websocket_handle
의 {reply
튜플가 웹 소켓에 회신하도록되어 있기 때문이라고 생각합니다 ..하지만이 사실이라면, 나는 데이터의 업데이트가 기대 :
websocket_info(myscreenupdate, State = {St,P, _}) ->
{reply, {text, <<"My screen update">>}, {St, P, <<"turn2">>}};
그래서 난 여기서 무슨 일이 일어나고 있는지 불확실합니다.
플레이어 프로세스에서 상태를 업데이트 한 다음 내 websocket 처리기에서 해당 상태를 검색하여 연결에 보내는 방법은 무엇입니까?
ws_handler.erl:
-module(ws_handler).
-export([init/2]).
-export([websocket_init/1]).
-export([websocket_handle/2]).
-export([websocket_info/2]).
init(Req, Opts) ->
{cowboy_websocket, Req, Opts}.
websocket_init(State) ->
{ok, State}.
websocket_handle({text, <<"h", Name/binary>>}, State) ->
{ok, PID} = player:go(self(), <<"profiledata", Name/binary>>),
erlang:start_timer(1000, self(), <<"Hello!">>),
{reply, {text, <<"You joined, ", Name/binary>>}, {State, PID, <<"turn1">>}};
websocket_handle({text, <<"myscreen">>}, S = {_, P, _}) ->
gen_server:call(P, myscreen),
{ok, S};
websocket_handle({text, <<"auth", Auth/binary>>}, S = {_St, P, _}) ->
case s:s(P, Auth) of
{ok, Valid} -> {reply, {text, << "Authorized">>}, S};
_ -> {reply, {text, <<"Error">>}, S}
end;
websocket_handle({text, Msg}, S = {_St, P, Outbox}) ->
{reply, {text, Outbox}, S};
websocket_handle(_Data, State) ->
{ok, State}.
websocket_info(myscreenupdate, State = {St,P, _}) ->
{reply, {text, <<"My screen update">>}, {St, P, <<"turn2">>}};
websocket_info({timeout, _Ref, _Ignored}, State = {_, P, Outbox}) ->
erlang:start_timer(1000, self(), <<"This is ignored">>),
Msg = Outbox,
{reply, {text, Msg}, State};
websocket_info(_Info, State) ->
{ok, State}.
player.erl : 문제는 그 카우보이의 websocket_info/2
핸들러는 동등의, 얼랑 내장 된 메시지 연산자 !
를 사용 (또는하여 웹 소켓 과정에 보낸 메시지를받을 것입니다
-module(player).
-compile(export_all).
handle_call(myscreen, _, {WS, Profile, Cab}) ->
gen_server:cast(WS, myscreenupdate),
{reply, ok, {WS, Profile, Cab}};
handle_call(get_profile, _, State = {_WSPID, Profile, _}) ->
{reply, Profile, State}.
init([WSPID, Profile]) ->
{ok, {WSPID, Profile, null}};
init([WSPID, Profile, CabinetPID]) ->
{ok, {WSPID, Profile, CabinetPID}}.
go(WSPID, Profile, CabinetPID) ->
gen_server:start_link(?MODULE, [WSPID, Profile, CabinetPID], []).
go(WSPID, Profile) ->
gen_server:start_link(?MODULE, [WSPID, Profile], []).
https://github.com/7stud/Programming-Erlang-Exercises-Solutions-Answers/blob/master/Chapter%2018/simple_example에 도움이되는 것이 있다면 여기를 참조하십시오.md – 7stud