Elixir 凤凰城+;渠道:如何确保双方;接受;?
苹果对视频聊天的部分要求是,双方在进入视频聊天之前必须明确按下“接受” 我有一个“接受”按钮,按下时调用此功能: 我的看法是:Elixir 凤凰城+;渠道:如何确保双方;接受;?,elixir,phoenix-framework,Elixir,Phoenix Framework,苹果对视频聊天的部分要求是,双方在进入视频聊天之前必须明确按下“接受” 我有一个“接受”按钮,按下时调用此功能: 我的看法是: channel.on("match_accepted", payload => { if (payload.matched_client_email == matchedClientEmail) { this.setState({ clientQueued: true }); } }); acceptMatch() {
channel.on("match_accepted", payload => {
if (payload.matched_client_email == matchedClientEmail) {
this.setState({ clientQueued: true });
}
});
acceptMatch() {
...
if (this.state.clientQueued) {
// start video session
} else {
// notify the other person that you have accepted
channel.push("accept_match", {
"matched_client_email": matchedClientEmail,
});
}
}
通话频道:
def handle_in("accept_match", %{ "matched_client_email" => matched_client_email }, socket) do
# broadcast to the other person that you have accepted
VideoChat.Endpoint.broadcast(
"user_pool:#{matched_client_email}",
"match_accepted",
%{ matched_client_email: socket.assigns[:email] }
)
{:noreply, socket}
end
这是非常脆弱的,因为我无法保证在用户按下按钮时,状态(这是一个react事件)已经更新。因此,他们可能会同时接受,并处于犹豫状态
有没有更好的办法确保双方都接受?我想通过Phoenix的状态库来实现这一点,并在metas
键中存储一个属性,但按照目前的方式,所有客户都在自己的频道/房间中,因此每个状态列表只会有一条记录(…对吗?)。在较高级别上,似乎聊天服务器应该是确定两个用户都接受的服务器。因此:
user1 presses accept -> sends "accept_match" to chat server
user2 presses accept -> sends "accept_match" to chat server
chat server sees both has accepted
-> broadcasts "start_session"
下面是一个快速示例,在每个会话中使用代理
,并在双方都接受的情况下进行广播。确实有一种更简单/更有效的方法可以做到这一点
视图:
频道呼叫:
def handle_in("accept_match", %{ "matched_client_email" => matched_client_email }, socket) do
Agent.update agent_session_pid, fn state ->
Map.put(state, socket.assigns[:email], true)
end
# check to see if we should broadcast acceptance
matched_accepted = Agent.get(agent_session_pid, &(Map.get(&1, matched_client_email)))
case matched_accepted do
true ->
# broadcast to each user
VideoChat.Endpoint.broadcast(
"user_pool:#{matched_client_email}",
"session_started",
%{ matched_client_email: socket.assigns[:email] }
)
VideoChat.Endpoint.broadcast(
"user_pool:#{socket.assigns[:email]}",
"session_started",
%{ matched_client_email: }
)
{:noreply, socket}
_ ->
{:noreply, socket}
end
end
哇,太棒了。非常感谢!特工到底是什么?agent\u session\u pid
从哪里来?
def handle_in("accept_match", %{ "matched_client_email" => matched_client_email }, socket) do
Agent.update agent_session_pid, fn state ->
Map.put(state, socket.assigns[:email], true)
end
# check to see if we should broadcast acceptance
matched_accepted = Agent.get(agent_session_pid, &(Map.get(&1, matched_client_email)))
case matched_accepted do
true ->
# broadcast to each user
VideoChat.Endpoint.broadcast(
"user_pool:#{matched_client_email}",
"session_started",
%{ matched_client_email: socket.assigns[:email] }
)
VideoChat.Endpoint.broadcast(
"user_pool:#{socket.assigns[:email]}",
"session_started",
%{ matched_client_email: }
)
{:noreply, socket}
_ ->
{:noreply, socket}
end
end