All Projects → asciibeats → elixir_ranch

asciibeats / elixir_ranch

Licence: MIT license
A guide on how to use Ranch with Elixir

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to elixir ranch

The-Stata-Guide
Files for the Stata Guide on Medium https://medium.com/the-stata-guide
Stars: ✭ 105 (+183.78%)
Mutual labels:  guide
http client
A http client written in C and pure socket, for understanding HTTP protocol. 用于理解 http 协议的 http 客户端
Stars: ✭ 27 (-27.03%)
Mutual labels:  socket
clojure-workshop
Basic Clojure training material for a one day workshop
Stars: ✭ 28 (-24.32%)
Mutual labels:  guide
hackthebox
Notes Taken for HTB Machines & InfoSec Community.
Stars: ✭ 286 (+672.97%)
Mutual labels:  guide
PortAuthority
🚢A simple and flexible Flask web app to scan ports on any IP address or domain
Stars: ✭ 14 (-62.16%)
Mutual labels:  socket
futurerestore-guide
A project covering the process of using Futurerestore to upgrade, downgrade, re-restore to an unsigned iOS firmware.
Stars: ✭ 14 (-62.16%)
Mutual labels:  guide
BruteSniffing Fisher
hacking tool
Stars: ✭ 24 (-35.14%)
Mutual labels:  socket
docker-style-guide
Haufe Docker Style Guide
Stars: ✭ 40 (+8.11%)
Mutual labels:  guide
micrOS
micrOS - mini automation OS for DIY projects requires reliable direct communication
Stars: ✭ 55 (+48.65%)
Mutual labels:  socket
easy-shell
A pure Python script to easily get a reverse shell
Stars: ✭ 48 (+29.73%)
Mutual labels:  socket
guide
A new feature guide component by react 🧭
Stars: ✭ 597 (+1513.51%)
Mutual labels:  guide
windows-sucks
How to survive in Windows world (as a developer who loves unix)
Stars: ✭ 85 (+129.73%)
Mutual labels:  guide
Python-Guide-for-Beginners
A guide for Beginners in Python to refer
Stars: ✭ 47 (+27.03%)
Mutual labels:  guide
guidelines
📒 Guidelines on random topics I have learnt so far
Stars: ✭ 27 (-27.03%)
Mutual labels:  guide
Pi-Pool
Cardano Stakepool on Raspberry Pi
Stars: ✭ 204 (+451.35%)
Mutual labels:  guide
procbridge
A super-lightweight IPC (Inter-Process Communication) protocol over TCP socket.
Stars: ✭ 118 (+218.92%)
Mutual labels:  socket
com2us cppNetStudy work
컴투스 C++ 네트워크 스터디 개인 작업 저장소
Stars: ✭ 32 (-13.51%)
Mutual labels:  socket
java6-to-java8
Guia para ajudar devs Java atualizarem sua certificação Java 6 para Java 8.
Stars: ✭ 42 (+13.51%)
Mutual labels:  guide
docs.sublimetext.io
Sublime Text Community Documentation
Stars: ✭ 145 (+291.89%)
Mutual labels:  guide
pw
Best websites a Programmer should visit
Stars: ✭ 27 (-27.03%)
Mutual labels:  guide

A guide on how to use Ranch with Elixir

Since the top search results where outdated and generally a bit unsatisfactory to me, here is my example based on the official Ranch guide for Erlang.

Configuration

Add Ranch to the list of dependencies in your mix.exs:

defp deps do
  [
    {:ranch, "~> 2.1"}
  ]
end

Protocols

In accordance with the official guide, I created a simple echo server, which just responds with the message one sends to it:

defmodule ElixirRanch.Protocols.Echo do
  @behaviour :ranch_protocol
  @timeout 5000

  def start_link(ref, transport, opts) do
    {:ok, spawn_link(__MODULE__, :init, [ref, transport, opts])}
  end

  def init(ref, transport, _opts) do
    {:ok, socket} = :ranch.handshake(ref)
    loop(socket, transport)
  end

  defp loop(socket, transport) do
    case transport.recv(socket, 0, @timeout) do
      {:ok, data} ->
        :ok = transport.send(socket, data)
        loop(socket, transport)
      _ ->
        transport.close(socket)
    end
  end
end

Or, if you like to use GenServer:

defmodule ElixirRanch.Protocols.EchoServer do
  use GenServer

  @behaviour :ranch_protocol
  @timeout 5000

  @impl true
  def start_link(ref, transport, opts) do
    {:ok, :proc_lib.spawn_link(__MODULE__, :init, [{ref, transport, opts}])}
  end

  @impl true
  def init({ref, transport, _opts}) do
    {:ok, socket} = :ranch.handshake(ref)
    :ok = transport.setopts(socket, active: :once)
    :gen_server.enter_loop(__MODULE__, [], {socket, transport}, @timeout)
  end

  @impl true
  def handle_info({:tcp, socket, data}, {socket, transport} = state) do
    :ok = transport.send(socket, data)
    :ok = transport.setopts(socket, active: :once)
    {:noreply, state, @timeout}
  end

  @impl true
  def handle_info(_, {socket, transport} = state) do
    transport.close(socket)
    {:stop, :shutdown, state}
  end
end

Listeners

For clarity I encapsulated both listeners in a module:

defmodule ElixirRanch.Listeners.Echo do
  def child_spec(opts) do
    :ranch.child_spec(__MODULE__, :ranch_tcp, opts, ElixirRanch.Protocols.Echo, [])
  end
end

Or for the GenServer:

defmodule ElixirRanch.Listeners.EchoServer do
  def child_spec(opts) do
    :ranch.child_spec(__MODULE__, :ranch_tcp, opts, ElixirRanch.Protocols.EchoServer, [])
  end
end

Then I embedded both listeners into a supervision tree:

defmodule ElixirRanch.ListenerSup do
  use Supervisor

  def start_link(args) do
    Supervisor.start_link(__MODULE__, args)
  end

  @impl true
  def init({}) do
    children = [
      {ElixirRanch.Listeners.Echo, [{:port, 5555}]},
      {ElixirRanch.Listeners.EchoServer, [{:port, 5556}]}
    ]
    
    Supervisor.init(children, strategy: :one_for_one)
  end
end

Application

To put it all together, I added the listener supervisor to an application file...

defmodule ElixirRanch.Application do
  use Application

  def start(_type, _args) do
    children = [
      {ElixirRanch.ListenerSup, {}}
    ]

    Supervisor.start_link(children, strategy: :one_for_one)
  end
end

...and added the application to my mix.exs, so it would start automatically:

def application do
  [
    mod: {ElixirRanch.Application, []}
  ]
end

Try it!

Clone this repo and get Ranch:

git clone https://github.com/asciibeats/elixir_ranch.git
cd elixir_ranch
mix deps.get

Start the server:

mix run --no-halt

Connect to it:

telnet localhost 5555

Type something, press ENTER and the server should respond with the same message. Wait five seconds for the connection to time out. Change the port to 5556 to try the protocol using GenServer. It should do the same.

I hope you found this little guide helpful!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].