[elixir! #0024] 엔진 덮개 아래'Channel.push`어떻게 작동합니까
Phoenix.Channel.push
처음 피닉스 프레임워크를 접했을 때 홈페이지의 강좌에 따라 채팅 페이지를 만들었다.서버는 채널에서 메시지를 방송할 수 있고,push 메시지를 한 사용자에게 보낼 수 있습니다.phoenix는 도대체 어떻게 한 거야?우리 먼저 이 함수의 정의를 보자 @doc """
Sends event to the socket.
The event's message must be a serializable map.
## Examples
iex> push socket, "new_message", %{id: 1, content: "hello"}
:ok
"""
def push(socket, event, message) do
%{transport_pid: transport_pid, topic: topic} = assert_joined!(socket)
Server.push(transport_pid, topic, event, message, socket.serializer)
end
우선 assert_joined!/1
함수를 호출해서 그것이 무슨 소용이 있는지 봅시다 defp assert_joined!(%Socket{joined: true} = socket) do
socket
end
defp assert_joined!(%Socket{joined: false}) do
raise """
`push`, `reply`, and `broadcast` can only be called after the socket has finished joining.
To push a message on join, send to self and handle in handle_info/2, ie:
def join(topic, auth_msg, socket) do
...
send(self, :after_join)
{:ok, socket}
end
def handle_info(:after_join, socket) do
push socket, "feed", %{list: feed_items(socket)}
{:noreply, socket}
end
"""
end
원래는 이 socket이 채널에 가입했는지 확인하는 것뿐입니다. 자세한 오류 알림을 되돌려줍니다. join에서push 메시지를 알려주는 것은 아마도 많은 사람들이 이 문제를 제기했기 때문일 것입니다.
socket에서 transport_pid
, topic
, serializer
함수를 가져온 후 Server.push
함수를 호출했습니다.
Phoenix.Channel.Server.push @doc """
Pushes a message with the given topic, event and payload
to the given process.
"""
def push(pid, topic, event, payload, serializer)
when is_binary(topic) and is_binary(event) and is_map(payload) do
encoded_msg = serializer.encode!(%Message{topic: topic,
event: event,
payload: payload})
send pid, encoded_msg
:ok
end
def push(_, _, _, _, _), do: raise_invalid_message()
Server.push
함수는 받은 topic
, event
및 payload
인코딩을 받아transport에 보냅니다.그렇다면transport는 이 정보들을 어떻게 처리합니까?
cowboy_websocket:handler_loop
클라이언트가 어떤 채널에 가입했을 때 도대체 무슨 일이 일어났는지 잠시 멈추자.클라이언트와 서버의 연결이 이루어지면transport 프로세스를 생성하고, 클라이언트가 특정channel에 가입하면transport 프로세스는channel 프로세스를 생성합니다.클라이언트가 연결을 끊으면transport 프로세스가 죽고 다음 채널 프로세스도 죽는다.그래서 모든 사용자가 가입한 모든 채널은 하나의 %Phoenix.Socket{}
구조체를 저장하는 데 사용되는 독립된 프로세스를 가지고 있다.
Observer를 통해 프로세스에서 실행 중인 함수 tansport
를 찾았습니다.그 후로 카우보이가 메시지를 웹소켓을 통해 클라이언트에게 보냈다.
총결산
phoenix channel의 메시지push 메커니즘은 매우 간단하고 같은 channel을 주목하는 다른 사람들과 관계가 없습니다.프로세스 관계 그림
다음에 우리는 피닉스가 어떻게 소식을 방송하는지 볼 것이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Elixir에서 한 번만 작업하기
일반적인 솔루션은 향후 호출자를 위해 계산된 값을 캐시하는 것이지만 콜드 캐시(또는 캐시된 값이 만료된 경우)에서는 여전히 함수가 여러 번 실행될 수 있습니다.
따라서 여러 프로세스가 GenServer 를 호출하면 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
@doc """
Sends event to the socket.
The event's message must be a serializable map.
## Examples
iex> push socket, "new_message", %{id: 1, content: "hello"}
:ok
"""
def push(socket, event, message) do
%{transport_pid: transport_pid, topic: topic} = assert_joined!(socket)
Server.push(transport_pid, topic, event, message, socket.serializer)
end
defp assert_joined!(%Socket{joined: true} = socket) do
socket
end
defp assert_joined!(%Socket{joined: false}) do
raise """
`push`, `reply`, and `broadcast` can only be called after the socket has finished joining.
To push a message on join, send to self and handle in handle_info/2, ie:
def join(topic, auth_msg, socket) do
...
send(self, :after_join)
{:ok, socket}
end
def handle_info(:after_join, socket) do
push socket, "feed", %{list: feed_items(socket)}
{:noreply, socket}
end
"""
end
@doc """
Pushes a message with the given topic, event and payload
to the given process.
"""
def push(pid, topic, event, payload, serializer)
when is_binary(topic) and is_binary(event) and is_map(payload) do
encoded_msg = serializer.encode!(%Message{topic: topic,
event: event,
payload: payload})
send pid, encoded_msg
:ok
end
def push(_, _, _, _, _), do: raise_invalid_message()
Server.push
함수는 받은 topic
, event
및 payload
인코딩을 받아transport에 보냅니다.그렇다면transport는 이 정보들을 어떻게 처리합니까?cowboy_websocket:handler_loop
클라이언트가 어떤 채널에 가입했을 때 도대체 무슨 일이 일어났는지 잠시 멈추자.클라이언트와 서버의 연결이 이루어지면transport 프로세스를 생성하고, 클라이언트가 특정channel에 가입하면transport 프로세스는channel 프로세스를 생성합니다.클라이언트가 연결을 끊으면transport 프로세스가 죽고 다음 채널 프로세스도 죽는다.그래서 모든 사용자가 가입한 모든 채널은 하나의 %Phoenix.Socket{}
구조체를 저장하는 데 사용되는 독립된 프로세스를 가지고 있다.
Observer를 통해 프로세스에서 실행 중인 함수 tansport
를 찾았습니다.그 후로 카우보이가 메시지를 웹소켓을 통해 클라이언트에게 보냈다.
총결산
phoenix channel의 메시지push 메커니즘은 매우 간단하고 같은 channel을 주목하는 다른 사람들과 관계가 없습니다.프로세스 관계 그림
다음에 우리는 피닉스가 어떻게 소식을 방송하는지 볼 것이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Elixir에서 한 번만 작업하기
일반적인 솔루션은 향후 호출자를 위해 계산된 값을 캐시하는 것이지만 콜드 캐시(또는 캐시된 값이 만료된 경우)에서는 여전히 함수가 여러 번 실행될 수 있습니다.
따라서 여러 프로세스가 GenServer 를 호출하면 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
phoenix channel의 메시지push 메커니즘은 매우 간단하고 같은 channel을 주목하는 다른 사람들과 관계가 없습니다.프로세스 관계 그림
다음에 우리는 피닉스가 어떻게 소식을 방송하는지 볼 것이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Elixir에서 한 번만 작업하기일반적인 솔루션은 향후 호출자를 위해 계산된 값을 캐시하는 것이지만 콜드 캐시(또는 캐시된 값이 만료된 경우)에서는 여전히 함수가 여러 번 실행될 수 있습니다. 따라서 여러 프로세스가 GenServer 를 호출하면 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.