Coder Social home page Coder Social logo

phoenix_client's Introduction

PhoenixClient

Channel client for connecting to Phoenix from Elixir

Installation

Add phoenix_client and a json library as dependencies in your mix.exs file. jason is specified as the default json library.

def deps do
  [
    {:phoenix_client, "~> 0.11"},
    {:jason, "~> 1.0"}
  ]
end

If you choose to use a different json library, you can set it through the socket options.

Usage

There are two things required to connect to a phoenix server using channels, a PhoenixClient.Socket and a PhoenixClient.Channel. The socket establishes the connection to the remote socket. The channel takes a topic and is used to join a remote channel. In the following example we will assume that we are attempting to communicate with a locally running phoenix server with a RoomChannel with the topic room:lobby configured to route to the RoomChannel in the UserSocket.

First, Lets create a client socket:

socket_opts = [
  url: "ws://localhost:4000/socket/websocket"
]

{:ok, socket} = PhoenixClient.Socket.start_link(socket_opts)

The socket will automatically attempt to connect when it starts. If the socket becomes disconnected, it will attempt to reconnect automatically. Please note that start_link is not synchronous so you must wait for the socket to become connected before attempting to join a channel.

You can control how frequently the socket will attempt to reconnect by setting reconnect_interval in the socket_opts.

Next, we will create a client channel and join the remote.

{:ok, _response, channel} = PhoenixClient.Channel.join(socket, "rooms:lobby")

Now that we have successfully joined the channel, we are ready to push and receive new messages. Pushing a message can be done synchronously or asynchronously. If you require a reply, or want to institute a time out, you can call push. If you do not require a response, you can call push_async.

In this example, we will assume the server channel has the following handle_in callbacks:

  def handle_in("new:msg", message, socket) do
    {:reply, {:ok, message}, socket}
  end

  def handle_in("new:msg_async", _message, socket) do
    {:noreply, socket}
  end
message = %{hello: :world}
{:ok, ^message} = PhoenixClient.Channel.push(channel, "new:msg", message)
:ok = PhoenixClient.Channel.push_async(channel, "new:msg_async", message)

Messages that are pushed or broadcasted to the client channel will be sent to the pid that called join. Messages will be of the of the struct %PhoenixClient.Message{}.

In this example we will assume the server channel has the following handle_in callback

  def handle_in("new:msg", message, socket) do
    push(socket, "incoming:msg", message)
    {:reply, :ok, socket}
  end
message = %{hello: :world}
{:ok, ^message} = PhoenixClient.Channel.push(channel, "new:msg", message)
flush

%PhoenixClient.Message{
  channel_pid: #PID<0.186.0>,
  event: "incoming:msg",
  payload: %{"hello" => "world"},
  ref: nil,
  topic: "room:lobby"
}

Common configuration

You can configure the socket to be started in your main application supervisor. You will need to name the socket so it can be referenced from your channel.

  socket_opts =
    Application.get_env(:phoenix_client, :socket)

  children = [
    {PhoenixClient.Socket, {socket_opts, name: PhoenixClient.Socket}}
  ]

You will need a socket for each server you are connecting to. Here is an example for connecting to multiple remote servers.

  socket_1_opts =
    Application.get_env(:phoenix_client, :socket_1)
  socket_2_opts =
    Application.get_env(:phoenix_client, :socket_2)

  children = [
    {PhoenixClient.Socket, {socket_1_opts, name: :socket_1, id: :socket_id_1}},
    {PhoenixClient.Socket, {socket_2_opts, name: :socket_1, id: :socket_id_2}}
  ]

Channels are usually constructed in a process such as a GenServer. Here is an example of how this is typically used.

defmodule MyApp.Worker do
  use GenServer

  alias PhoenixClient.{Socket, Channel, Message}

  # start_link ...

  def init(_opts) do
    {:ok, _response, channel} = Channel.join(Socket, "room:lobby")
    {:ok, %{
      channel: channel
    }}
  end

  # do some work, call `Channel.push` ...

  def handle_info(%Message{event: "incoming:msg", payload: payload}, state) do
    IO.puts "Incoming Message: #{inspect payload}"
    {:noreply, state}
  end
end

phoenix_client's People

Contributors

connorrigby avatar fhunleth avatar fkumro avatar indrekj avatar malroc avatar mobileoverlord avatar mortadaak avatar oestrich avatar paulstatezny avatar pinx avatar raphexion avatar slashmili avatar th0mas avatar tlvenn avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.