brandonhamilton / purescript-phoenix

Phoenix Framework bindings for PureScript
MIT License
6 stars 6 forks source link

Do you have examples usage? #1

Open peerst opened 7 years ago

peerst commented 7 years ago

It would be very nice and make it much easier to get into your library if there were some examples.

Would help a lot to just take what you have and add a examples subdir

Cheers, -- Peer

brandonhamilton commented 7 years ago

I do still need to create a full example that includes the phoenix backend.

For now, here is an example showing how the library can be used in a basic echo service:

module Main where

import Prelude (Unit, bind, (<>), ($), show)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Foreign (toForeign)
import Phoenix
import Data.Options ((:=))

socketOpened :: forall e. Socket -> Eff (console :: CONSOLE, phoenix :: PHOENIX | e) Unit
socketOpened s = do  
  url <- endPointURL s
  log $ "* Socket has been opened to " <> url
  connected <- isConnected s
  log $ "* Socket connected: " <> show connected

  chan <- channel s "room:lobby" (toForeign {})
  -- Register callbacks
  onChannelError chan \c err -> do
    log $ "* Error on channel" <> err

  on chan "hello" \c e msg -> do
    log $ "--> " <> e <> ": "

  -- Join
  res <- join chan
  receive res "ok" \p e -> do
    log $ "Joined channel"
    res2 <- push chan "hello" (toForeign {"body": "test"})
    receive res2 "ok" \p2 e2 -> do
      log $ "Said hello"
    receive res2 "error" \p2 e2 -> do
      log $ "Error saying hello"

  receive res "error" \p e -> do
    log $ "Failed to join channel "

  log "* Socket open completed"

main :: forall e. Eff (console :: CONSOLE, phoenix :: PHOENIX | e) Unit
main = do
  log "1. Creating"
  -- Alternatively use `defaultSocketOptions` for options
  sock <- newSocket "ws://localhost:4000/socket" (timeout := 1000 <> heartbeatIntervalMs := 3000)

  log "2. Registering callbacks"
  -- Register callbacks 
  onOpen sock socketOpened
  onMessage sock \s msg -> do
    log $ "* Message from socket: " <> msg.topic

  onSocketError sock \s err -> do
    log $ "* Error on socket" <> err

  onSocketClose sock \s reason -> do
    log $ "* Socket been closed: " <> reason

  log "3. Socket created"
  connect sock
  connected <- isConnected sock
  log $ "4. Socket connected: " <> show connected

Where the phoenix side is simply:

defmodule PurescriptBackend.RoomChannel do
  use Phoenix.Channel

  def join("room:lobby", _message, socket) do
    {:ok, socket}
  end

  def handle_in("hello", %{"body" => body}, socket) do
    broadcast! socket, "hello", %{body: body}
    {:noreply, socket}
  end

  def handle_out("hello", payload, socket) do
    push socket, "hello", payload
    {:noreply, socket}
  end

end
peerst commented 7 years ago

Thanks this will help a lot. We are not using the full Elixir Phoenix but a minimal implementation of Phoenix Channel protocol in Erlang