Current section
Files
Jump to
Current section
Files
lib/kvasir/agent_server/control/protocol.ex
defmodule Kvasir.AgentServer.Control.Protocol do
def start_link(ref, transport, config) do
{:ok, spawn_link(__MODULE__, :init, [ref, transport, config])}
end
def init(ref, transport, {server, protocol}) do
# Apply to not warn for client only
{:ok, socket} = apply(:ranch, :handshake, [ref])
transport.send(socket, ["HELLO ", to_string(System.system_time(:second)), ?\n])
protocol.init(socket, transport, server)
loop(socket, transport, server, protocol, [])
end
defp loop(socket, transport, server, protocol, buffer) do
case transport.recv(socket, 0, :infinity) do
{:ok, data} ->
loop(
socket,
transport,
server,
protocol,
process_data(socket, transport, server, protocol, data, buffer)
)
_err ->
:ok = transport.close(socket)
protocol.close(server)
end
end
defp process_data(socket, transport, server, protocol, data, buffer) do
case String.split(data, ~r/\r?\n/) do
[b] -> [b | buffer]
process -> handle_commands(socket, transport, server, protocol, process, buffer)
end
end
defp handle_commands(socket, transport, server, protocol, received, []),
do: handle_loop(socket, transport, server, protocol, received)
defp handle_commands(socket, transport, server, protocol, [r | received], buffer) do
b = :erlang.iolist_to_binary(:lists.reverse([r | buffer]))
handle_commands(socket, transport, server, protocol, [b | received], [])
end
defp handle_loop(_socket, _transport, _server, _protocol, [""]), do: []
defp handle_loop(_socket, _transport, _server, _protocol, [b]), do: [b]
defp handle_loop(socket, transport, server, protocol, [cmd | received]) do
case String.split(cmd, ~r/\s+/, trim: true) do
[] -> :ok
["PING"] -> transport.send(socket, "PONG\n")
c -> with {:reply, d} <- protocol.handle_command(c, server), do: transport.send(socket, d)
end
handle_loop(socket, transport, server, protocol, received)
end
end