diff options
author | jeffweiss <jeff.weiss@puppetlabs.com> | 2014-11-24 00:24:37 -0800 |
---|---|---|
committer | jeffweiss <jeff.weiss@puppetlabs.com> | 2014-11-24 00:24:37 -0800 |
commit | 56e1e06e0e3c44c58f02a73be5feed3a51dd3608 (patch) | |
tree | c6abd0633576ac48848ed57ef74bf5057848d1e8 /README.md | |
parent | Version 0.9.0 (diff) |
create example client application. Close #13.
Prior to this commit, the README illustrated a simplified version of a
client; however, this simplified version did not actually join the
specified channel because logon takes a non-trivial amount of time and
the code, as illustrated in the README, will immediately attempt to join
a channel even though we're not fully logged on yet. This has taken
several people quite a while to figure out. This commit adds an example
application (along with a stripped down version on it in the README)
with 3 handlers: Connection, Login, and business logic.
The ConnectionHandler is responsible to initiating the connection to the
IRC server and then when we've received a message that we've connected,
initiating the logon process. The LoginHandler waits until we've
received the logged_in message and then attempts to join the channels.
Next the bot's OhaiHandler will greet people as they enter the channels
that itself had just joined.
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 102 |
1 files changed, 102 insertions, 0 deletions
@@ -81,3 +81,105 @@ defmodule ExampleSupervisor do end end ``` + +A more robust example usage will wait until connected before it attempts to logon and then wait until logged +on until it attempts to join a channel. Please see the `examples` directory for more in-depth examples cases. + +```elixir + +defmodule ExampleApplication do + use Application + + # See http://elixir-lang.org/docs/stable/elixir/Application.html + # for more information on OTP Applications + def start(_type, _args) do + import Supervisor.Spec, warn: false + + {:ok, client} = ExIrc.start_client! + + children = [ + # Define workers and child supervisors to be supervised + worker(ExampleConnectionHandler, [client]), + # here's where we specify the channels to join: + worker(ExampleLoginHandler, [client, ["#ohaibot-testing"]]) + ] + + # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html + # for other strategies and supported options + opts = [strategy: :one_for_one, name: ExampleApplication.Supervisor] + Supervisor.start_link(children, opts) + end +end + +defmodule ExampleConnectionHandler do + defmodule State do + defstruct host: "chat.freenode.net", + port: 6667, + pass: "", + nick: "bitwalker", + user: "bitwalker", + name: "Paul Schoenfelder", + client: nil + end + + def start_link(client, state \\ %State{}) do + GenServer.start_link(__MODULE__, [%{state | client: client}]) + end + + def init([state]) do + ExIrc.Client.add_handler state.client, self + ExIrc.Client.connect! state.client, state.host, state.port + {:ok, state} + end + + def handle_info({:connected, server, port}, state) do + debug "Connected to #{server}:#{port}" + ExIrc.Client.logon state.client, state.pass, state.nick, state.user, state.name + {:noreply, state} + end + + # Catch-all for messages you don't care about + def handle_info(msg, state) do + debug "Received unknown messsage:" + IO.inspect msg + {:noreply, state} + end + + defp debug(msg) do + IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset() + end +end + +defmodule ExampleLoginHandler do + @moduledoc """ + This is an example event handler that listens for login events and then + joins the appropriate channels. We actually need this because we can't + join channels until we've waited for login to complete. We could just + attempt to sleep until login is complete, but that's just hacky. This + as an event handler is a far more elegant solution. + """ + def start_link(client, channels) do + GenServer.start_link(__MODULE__, [client, channels]) + end + + def init([client, channels]) do + ExIrc.Client.add_handler client, self + {:ok, {client, channels}} + end + + def handle_info(:logged_in, state = {client, channels}) do + debug "Logged in to server" + channels |> Enum.map(&ExIrc.Client.join client, &1) + {:noreply, state} + end + + # Catch-all for messages you don't care about + def handle_info(_msg, state) do + {:noreply, state} + end + + defp debug(msg) do + IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset() + end +end +``` |