{"id":20091323,"url":"https://github.com/mobileoverlord/phoenix_client","last_synced_at":"2025-12-12T00:23:34.403Z","repository":{"id":46111827,"uuid":"39416033","full_name":"mobileoverlord/phoenix_client","owner":"mobileoverlord","description":"Elixir Phoenix Client for Channels","archived":false,"fork":false,"pushed_at":"2021-03-11T16:34:10.000Z","size":152,"stargazers_count":215,"open_issues_count":8,"forks_count":55,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-13T04:59:28.601Z","etag":null,"topics":["channels","phoenix"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mobileoverlord.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-21T00:57:28.000Z","updated_at":"2025-03-18T04:18:25.000Z","dependencies_parsed_at":"2022-08-25T11:00:15.499Z","dependency_job_id":null,"html_url":"https://github.com/mobileoverlord/phoenix_client","commit_stats":null,"previous_names":["mobileoverlord/phoenix_channel_client"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobileoverlord%2Fphoenix_client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobileoverlord%2Fphoenix_client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobileoverlord%2Fphoenix_client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mobileoverlord%2Fphoenix_client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mobileoverlord","download_url":"https://codeload.github.com/mobileoverlord/phoenix_client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665757,"owners_count":21142123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["channels","phoenix"],"created_at":"2024-11-13T16:29:35.845Z","updated_at":"2025-12-12T00:23:34.373Z","avatar_url":"https://github.com/mobileoverlord.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PhoenixClient\n\nChannel client for connecting to Phoenix from Elixir\n\n## Installation\n\nAdd `phoenix_client` and a json library as dependencies in your `mix.exs` file.\n`jason` is specified as the default json library.\n\n```elixir\ndef deps do\n  [\n    {:phoenix_client, \"~\u003e 0.3\"},\n    {:jason, \"~\u003e 1.0\"}\n  ]\nend\n```\n\nIf you choose to use a different json library, you can set it through the\nsocket options.\n\n## Usage\n\nThere are two things required to connect to a phoenix server using channels, a\n`PhoenixClient.Socket` and a `PhoenixClient.Channel`. The socket establishes\nthe connection to the remote socket. The channel takes a topic and is used\nto join a remote channel. In the following example we will assume that we are\nattempting to communicate with a locally running phoenix server with a `RoomChannel`\nwith the topic `room:lobby` configured to route to the `RoomChannel`\nin the `UserSocket`.\n\nFirst, Lets create a client socket:\n\n```elixir\nsocket_opts = [\n  url: \"ws://localhost:4000/socket/websocket\"\n]\n\n{:ok, socket} = PhoenixClient.Socket.start_link(socket_opts)\n```\n\nThe socket will automatically attempt to connect when it starts. If the socket\nbecomes disconnected, it will attempt to reconnect automatically.\nPlease note that `start_link` is not synchronous so you must wait for the\nsocket to become connected before attempting to join a channel.\n\nYou can control how frequently the socket will attempt to reconnect by setting\n`reconnect_interval` in the socket_opts.\n\nNext, we will create a client channel and join the remote.\n\n```elixir\n{:ok, _response, channel} = PhoenixClient.Channel.join(socket, \"rooms:lobby\")\n```\n\nNow that we have successfully joined the channel, we are ready to push and receive\nnew messages. Pushing a message can be done synchronously or asynchronously. If\nyou require a reply, or want to institute a time out, you can call `push`. If\nyou do not require a response, you can call `push_async`.\n\nIn this example, we will assume the server channel has the following `handle_in`\ncallbacks:\n\n```elixir\n  def handle_in(\"new:msg\", message, socket) do\n    {:reply, {:ok, message}, socket}\n  end\n\n  def handle_in(\"new:msg_async\", _message, socket) do\n    {:noreply, socket}\n  end\n```\n\n```elixir\nmessage = %{hello: :world}\n{:ok, ^message} = PhoenixClient.Channel.push(channel, \"new:msg\", message)\n:ok = PhoenixClient.Channel.push_async(channel, \"new:msg_async\", message)\n```\n\nMessages that are pushed or broadcasted to the client channel will be sent to the\npid that called `join`. Messages will be of the of the struct `%PhoenixClient.Message{}`.\n\nIn this example we will assume the server channel has the following `handle_in`\ncallback\n\n```elixir\n  def handle_in(\"new:msg\", message, socket) do\n    push(socket, \"incoming:msg\", message)\n    {:reply, :ok, socket}\n  end\n```\n\n```elixir\nmessage = %{hello: :world}\n{:ok, ^message} = PhoenixClient.Channel.push(channel, \"new:msg\", message)\nflush\n\n%PhoenixClient.Message{\n  channel_pid: #PID\u003c0.186.0\u003e,\n  event: \"incoming:msg\",\n  payload: %{\"hello\" =\u003e \"world\"},\n  ref: nil,\n  topic: \"room:lobby\"\n}\n```\n\n### Common configuration\n\nYou can configure the socket to be started in your main application supervisor.\nYou will need to name the socket so it can be referenced from your channel.\n\n```elixir\n  socket_opts =\n    Application.get_env(:phoenix_client, :socket)\n\n  children = [\n    {PhoenixClient.Socket, {socket_opts, name: PhoenixClient.Socket}}\n  ]\n```\n\nYou will need a socket for each server you are connecting to. Here is an example\nfor connecting to multiple remote servers.\n\n```elixir\n  socket_1_opts =\n    Application.get_env(:phoenix_client, :socket_1)\n  socket_2_opts =\n    Application.get_env(:phoenix_client, :socket_2)\n\n  children = [\n    {PhoenixClient.Socket, {socket_1_opts, name: :socket_1, id: :socket_id_1}},\n    {PhoenixClient.Socket, {socket_2_opts, name: :socket_1, id: :socket_id_2}}\n  ]\n```\n\nChannels are usually constructed in a process such as a `GenServer`. Here is an\nexample of how this is typically used.\n\n```elixir\ndefmodule MyApp.Worker do\n  use GenServer\n\n  alias PhoenixClient.{Socket, Channel, Message}\n\n  # start_link ...\n\n  def init(_opts) do\n    {:ok, _response, channel} = Channel.join(Socket, \"room:lobby\")\n    {:ok, %{\n      channel: channel\n    }}\n  end\n\n  # do some work, call `Channel.push` ...\n\n  def handle_info(%Message{event: \"incoming:msg\", payload: payload}, state) do\n    IO.puts \"Incoming Message: #{inspect payload}\"\n    {:noreply, state}\n  end\nend\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobileoverlord%2Fphoenix_client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmobileoverlord%2Fphoenix_client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmobileoverlord%2Fphoenix_client/lists"}