0

내 피닉스 1.3 응용 프로그램에 채팅 기능을 추가하기 위해 함께 피닉스 채널, 토큰존재 모듈을 묶을려고합니다. 3 가지 모듈 모두를 함께 사용할 수 없었습니다. 마지막 오류는 connection to websocket closed before handshake입니다. 이제 오류가 발생하지 않지만 소켓에도 연결되지 않습니다.연결 피닉스 토큰과 소켓 및 현재

저는이 문제가 player_socket.ex의 "연결"기능이라고 생각합니다. (나는 플레이어 리소스가있다). 다음은 함수입니다.

def connect(%{"token" => token}, socket) do 
     case Phoenix.Token.verify(socket, "player auth", token, max_age: @max_age) do 
     {:ok, player_id} -> 
      player = Repo.get!(Player, player_id) 
      {:ok, assign(socket, :current_player, player)} 
      {:error, _reason} -> 
      :error 
     end 
    end 

app.html.eex의 메타 태그에 토큰에 서명하고 있습니다.

<%= tag :meta, name: "channel_token", content: Phoenix.Token.sign(@conn, "player auth", :player_id) %> 그런 다음 lobby_channel.ex에서 I는 채널에 가입하기 위해 노력하고있어 :

def join("lobby:lobby", _params, socket) do 
    send(self(), :after_join) 
    {:ok, assign(socket, :player_id, :current_player)} 
    end 

    def handle_info(:after_join, socket) do 
    push socket, "presence_state", Presence.list(socket) 
    {:ok, _} = Presence.track(socket, socket.assigns.current_player, %{ 
     online_at: inspect(System.system_time(:seconds)) 
    }) 
    {:noreply, socket} 
    end 

내가 문서 읽기를하지만 함께 웹 소켓에 연결할 수없는거야 이유를 알아낼 수 없습니다 Presence를 사용하여 온라인 상태 인 사람과 플레이어의 이름을 채팅 메시지와 연관시킬 수 있도록 "current_player" 어떤 통찰력이라도 대단히 감사합니다! 나는 여기에 환매 특약이 있습니다. 나는 current_player "로 CONN에서 플레이어 구조체를 저장하기 위해"current_player "플러그를 사용하고

https://github.com/EssenceOfChaos/gofish

UPDATE를

다음
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, 
assigns: %{current_player: %Gofish.Accounts.Player{__meta__: #Ecto.Schema.Metadata<:loaded, "players">, 
    email: "[email protected]", id: 6, 

내 업데이트됩니다 lobby_channel.ex :

def join("lobby:lobby", _params, socket) do 
    send(self(), :after_join) 
    {:ok, socket} 
    end 

    def handle_info(:after_join, socket) do 
    push socket, "presence_state", Presence.list(socket) 
    {:ok, _} = Presence.track(socket, socket.assigns.current_player.id, %{ 
     username: socket.assigns.current_player.username, 
     online_at: inspect(System.system_time(:seconds)) 
    }) 
    {:noreply, socket} 
    end 

답변

0

player_socket.ex은 괜찮습니다. 하지만 EW 문제 :

당신의 layout/app.eex 템플릿에서

:

Phoenix.Token.sign(@conn, "player auth", :player_id)은 말 그대로 원자 :player_id 대신 플레이어의 ID를 쓰고있다. 플레이어의 ID를 작성하려면 @player_id를 사용해야 그래서처럼 router.ex에 전 세계적으로 값을 할당하는 플러그인을 추가

pipeline :browser do 
    [...] 
    plug :fetch_current_user 
end 

... 

def fetch_current_user(conn, _) do 
    assigns(conn, :current_player, get_session(conn, :current_player) 
end 

이 모든 템플릿에서 @current_player 제공 할 것입니다, 어떤 당신이 다음 수

<%= tag :meta, name: "channel_token", content: Phoenix.Token.sign(@conn, "player auth", @current_player) %> 

이 ( @current_playernil되지 않은 경우 조건이 작성해야하고 BTW, 경우 웹 소켓 연결을 시도에서 JS 클라이언트를 중지)

: app.eex에 사용

로그인 한 상태에서이 변경 사항을 적용하면 즉시 websocket에 연결할 수 없지만 문제가 하나 더 남아 있습니다. loby_channel.ex{:ok, assign(socket, :player_id, :current_player)}:current_player 글자 그대로 실제 값 대신 현재 플레이어의 ID이지만이 라인이 전혀 필요하지 않습니다.대신, :after_join에, 당신은 내가 socket.assigns.current_player.usernamesocket.assigns.current_player을 변경

{:ok, _} = Presence.track(socket, socket.assigns.current_player.username, %{ 
    online_at: inspect(System.system_time(:seconds)) 
}) 

주의를해야한다. 구조체를 현재 상태 키로 지정할 수 없기 때문입니다.

또는 당신이

{:ok, _} = Presence.track(socket, socket.assigns.current_player.id, %{ 
    username: socket.assigns.current_player.username, 
    online_at: inspect(System.system_time(:seconds)) 
}) 

과에서 할 수있는 당신의 socket.js 당신이 renderOnlineUsers

+0

대답 할 시간을내어 주셔서 감사합니다 내부 first.username 대신 id 사용하십시오! 당신이 옳았습니다. 실제 ID가 아닌 "player_id"원자를 할당했습니다. 나는 여전히 토큰에 대한 가치를 얻었 기 때문에주의를 기울이지 않았다. --- 전송 : WS에 연결 : // localhost를 : 나는이 웹 소켓에 연결하고 지금 그래서 나는 확실히 일부 진전 만들었어요? 4000/소켓/웹 소켓을 토큰 = SFMyNTY.g3QAAAACZAAEZGF0YWEGZAAGc2lnbmVkbgYAcXFphWAB.JzSzRcaWpebtBk2kH5ooeqKr8ez3Lxi8IuyRkuh0qxU 및 VSN = 2.0.0 정의되지 않은 --- 하지만 현재 상태 모듈에 온라인 사용자가 표시되지 않습니다. socket.js에서 "first.username"을 사용하려고합니다. –

+0

아, 그 오류는 지적하고 싶지 않습니다. 귀하의'socket.js'에'chatInput = document.querySelector ("# chat-input ");하지만 실제로는'let chatInput = document.querySelector ("# chatInput ");'이 템플릿에 ID를 작성한 방법입니다. – Mario

+0

이제 로그인 한 사용자가 표시됩니다. 답변 주셔서 감사합니다! 다른 브라우저로 로그인하고 새 계정을 등록하면 두 번 로그인 한 동일한 사용자가 표시됩니다. 그 이유는 무엇입니까? –