defmoduleExile.Mixfile do useMix.Project defprojectdo [app::exile, version:"0.0.1", elixir:"~> 1.0", deps: deps] end defapplicationdo [applications: [:logger]] end defpdepsdo [ {:socket, "~> 0.2.8"} ] end end
defmoduleExile.Bot do useGenServer @doc""" 调用start_link初始化,传递一个状态state, state是一个Map, 比如: %{ host: "irc.freenode.net", port: 6667, chan: "#elixir-lang", nick:"elixir-bot", sock: socket } """ def start_link(state) do GenServer.start_link(__MODULE__, state) end @doc """ 创建一个到IRC服务器的套接字连接 """ def init(state) do {:ok, sock} = Socket.TCP.connect(state.host, state.port, packet: :line) # 第三个参数0标识超时, 0为立即超时,并发生一个:timeout消息 {:ok, %{state | sock: sock}, 0} end @doc """ 超时处理回调函数 """ def handle_info(:timeout, state) do IO.puts "TIMEOUT HANDLED" { :noreply, state } end end
连接到IRC服务器
1 2 3 4
defhandle_info(:timeout, state) do state |> do_join_channel |> do_listen { :noreply, state } end
进入一个频道
1 2 3 4 5 6
defpdo_join_channel(%{sock: sock} = state) do sock |> Socket.Stream.send!("NICK #{state.nick}\r\n") sock |> Socket.Stream.send!("USER #{state.nick}#{state.host}#{state.nick}#{state.nick}\r\n") sock |> Socket.Stream.send!("JOIN #{state.chan}\r\n") state end
监听回复信息
进入频道后就可以通过下面的回调获取聊天信息
1 2 3 4 5 6 7 8 9 10 11 12
defpdo_listen(%{sock: sock} = state) do case state.sock |> Socket.Stream.recv! do data when is_binary(data)-> case parse_message(data, sock) do message -> message end do_listen(state) nil -> :ok end end