Skip to content

Instantly share code, notes, and snippets.

@chrismccord
Last active February 12, 2016 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrismccord/0a3bf5229801d61f219b to your computer and use it in GitHub Desktop.
Save chrismccord/0a3bf5229801d61f219b to your computer and use it in GitHub Desktop.
Phoenix Upgrade Instructions 0.12.x 0.13.0

Deps

First, clean your deps to avoid phoenix_html conflicts:

$ mix deps.clean phoenix --all

Next, bump phoenix:

{:phoenix, "~> 0.13"},

Update to the latest phoenix_live_relooad in mix.exs:

{:phoenix_live_reload, "~> 0.4"},

If using Ecto, Update to the latest phoenix_ecto in mix.exs:

{:phoenix_ecto, "~> 0.4"},

The HTML engine and helpers have been extracted into a phoenix_html project. If you are using *html.eex templates, simply add the dep to your mix.exs:

 {:phoenix_html, "~> 1.0"},

Make sure to run mix deps.get and you should be set on deps.

Channels

Minor changes to the server and client have been added. The return signatures of join/3 have changed. You can now reply directly on join, and you return {:error, reason} to refuse joining a channel. The javascript client has also be refactored to avoid the giant "receive ok" callback.

First update your web/static/js/vendor/phoenix.js file with: the 0.13 version

Next update your client and server code:

0.12.0:

def join("rooms:lobby", _, socket ) do
  send(self, :after_join)
  {:ok, socket}
end
def join("rooms:" <> _priv_id, _, socket) do
  :ignore
end

def handle_info(:after_join, socket) do
  push socket, "catchup", %{messages: Repo.all(Message)};
  {:noreply, socket}
end
let socket = new Phoenix.Socket("/ws")
let chan = socket.join("rooms:lobby", {})
chan.receive("ok", () => {
  chan.on("catchup", ({messages}) => ...)
  chan.on("some_event", ...)
})

0.13.0:

def join("rooms:lobby", _, socket ) do
  {:ok, %{messages: Repo.all(Message)}, socket}
end
def join("rooms:" <> _priv_id, _, socket) do
  {:error, %{reason: "unauthorized"}
end
let socket = new Phoenix.Socket("/ws")
let chan = socket.chan("rooms:lobby", {})

chan.on("some_event", ...)

chan.join().receive("ok", ({messages}) => {
  ...
})

Channel Params

The concept of 'channel params' has been added to the clients. Params are what is sent up as the second argument on join/3, but we have given them a clear name and you can now modify the params which will be passed up on every reconnect, ie imagine a game where we have a game lobby and private game rooms that require information passed to the lobby. We can store a passed player ID and token on the chan.params which will be passed back up to the server on reconnects:

let chan = socket.chan("lobby", {})

chan.join().receive("ok", ({player_id, player_token}) => {
  chan.params["player_id"] = player_id 
  chan.params["player_token"] = player_token
})

...

let gameChan = socket.chan("games:" + game_id, {
  player_id: chan.params.player_id, 
  player_token: chan.params.player_token
})

gameChan.join().receive("ok", () => console.log("Welcome to the game!") )
defmodule MyApp.LobbyChannel do
  ...
  def join("lobby", %{}, socket) do
    {player_id, player_token} = something_that_gets_these_things()
    {:ok, %{player_id: player_id, player_token: player_token}, socket}
  end
  def join("lobby", %{"player_id" => player_id, "player_token" => player_token}, socket) do
    # we've already issued a player_id, client is reconnecting with it, verify the token
    {:ok, %{player_id: player_id, player_token: player_token}, socket}
  end
  
  ...


defmodule MyApp.GameChannel do
  ...
  def join("games:" <> game_id, %{"player_id" => player_id, "player_token" => player_token}, socket) do
    # verify player_token
    {:ok, socket}
  end
  
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment