2017-02-17 2 views
1

У меня есть приложение, в котором 2 человека чат. Но прежде, чем они беседуют, обе стороны должны нажать «принять»Phoenix: Как хранить состояние, разделяемое через сокеты в канале?

на переднем конце у меня есть кнопка, которая вызывает эту функцию:

function acceptMatch() { 
    channel.push("accept_match", { 
    "matched_client_email": matchedClientEmail, 
    }); 
} 

в моем феникс канале у меня есть это (который является неполным, потому что я не уверен, что делать):

def handle_in("accept_match", %{ "matched_client_email" => matched_client_email }, socket) do 
    Logger.info "accept_match" 
    ... 
    ############################### here #################################### 
    match_accepted = true # <-- I want to be able to find out if the other person has pressed "accept" as well 
    case match_accepted do 
     true -> 
     ... 
     {:noreply, socket} 
     _ -> 
     {:noreply, socket} 
    end 
    end 

Я посмотрел в Agent, но это, кажется, привязан к PID, который я не смог бы легко пройти вокруг различных сокетов. Я пытаюсь найти общее хранилище (кроме базы данных) между всеми подключениями, которые я могу сохранить в/query. Таким образом, если партия A нажата, я могу спросить о хранении «принимала ли сторона B?»

=== UPDATE ===

Когда я пытаюсь использовать именованный Agent Я получаю:

iex(11)> myfunc = fn -> %{} end 
#Function<20.52032458/0 in :erl_eval.expr/5> 
iex(12)> Agent.start_link(myfunc, name: "Cool") 
** (CaseClauseError) no case clause matching: {"Cool", []} 
    (elixir) lib/gen_server.ex:544: GenServer.do_start/4 
iex(12)> 

ответ

2

На самом деле, кажется, что вы могли бы перейти к каждому новому соединению в connect в вашей user_socket это конкретный PID или имя Агента, и он должен решить этот случай. Вам нужен только один агент, поэтому вы можете его назвать, например.

Agent.start_link(your_func, name: :myagent) 

, а затем получить от него

Agent.get(:myagent, your_get_func) 

Также вы можете рассмотреть возможность использования Registry, который из Эликсир 1.4 в стандартной библиотеке.

Этот агент может быть в lib, и вы можете просто добавить его в файл <app_name>.ex в качестве отдельного работника и, при необходимости, контролировать его с помощью специального диспетчера.

+0

ooo прохладный! когда я пытался это сделать, я получаю сообщение об ошибке ... обновил свой вопрос с ошибкой – Edmund

+0

выглядит так, как будто это работает, когда это атом! 'имя:: cool' – Edmund

+0

Да, извините. Я обновил свой ответ. Имя должно соответствовать требованиям в https://hexdocs.pm/elixir/GenServer.html#module-name-registration – PatNowak