• Stars
    star
    680
  • Rank 63,851 (Top 2 %)
  • Language
    JavaScript
  • Created about 10 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple Chat Example

Built with the Phoenix Framework

To start your new Phoenix application you have to:

  1. Clone this repo, then cd to the new directory
  2. Install dependencies with mix deps.get
  3. (optional) Install npm dependencies to customize the ES6 js/Sass npm install
  4. Start Phoenix router with mix phx.server

Now you can visit localhost:4000 from your browser.

Live Demo

http://phoenixchat.herokuapp.com

Example Code

JavaScript

import {Socket, LongPoller} from "phoenix"

class App {

  static init(){
    let socket = new Socket("/socket", {
      logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) })
    })

    socket.connect({user_id: "123"})
    var $status    = $("#status")
    var $messages  = $("#messages")
    var $input     = $("#message-input")
    var $username  = $("#username")

    socket.onOpen( ev => console.log("OPEN", ev) )
    socket.onError( ev => console.log("ERROR", ev) )
    socket.onClose( e => console.log("CLOSE", e))

    var chan = socket.channel("rooms:lobby", {})
    chan.join().receive("ignore", () => console.log("auth error"))
               .receive("ok", () => console.log("join ok"))
               .after(10000, () => console.log("Connection interruption"))
    chan.onError(e => console.log("something went wrong", e))
    chan.onClose(e => console.log("channel closed", e))

    $input.off("keypress").on("keypress", e => {
      if (e.keyCode == 13) {
        chan.push("new:msg", {user: $username.val(), body: $input.val()})
        $input.val("")
      }
    })

    chan.on("new:msg", msg => {
      $messages.append(this.messageTemplate(msg))
      scrollTo(0, document.body.scrollHeight)
    })

    chan.on("user:entered", msg => {
      var username = this.sanitize(msg.user || "anonymous")
      $messages.append(`<br/><i>[${username} entered]</i>`)
    })
  }

  static sanitize(html){ return $("<div/>").text(html).html() }

  static messageTemplate(msg){
    let username = this.sanitize(msg.user || "anonymous")
    let body     = this.sanitize(msg.body)

    return(`<p><a href='#'>[${username}]</a>&nbsp; ${body}</p>`)
  }

}

$( () => App.init() )

export default App

Endpoint

# lib/chat/endpoint.ex
defmodule Chat.Endpoint do
  use Phoenix.Endpoint

  socket "/socket", Chat.UserSocket
  ...
end

Socket

# web/channels/user_socket.ex
defmodule Chat.UserSocket do
  use Phoenix.Socket

  channel "rooms:*", Chat.RoomChannel

  transport :websocket, Phoenix.Transports.WebSocket
  transport :longpoll, Phoenix.Transports.LongPoll
  ...
end

Channel

defmodule Chat.RoomChannel do
  use Phoenix.Channel
  require Logger

  def join("rooms:lobby", message, socket) do
    Process.flag(:trap_exit, true)
    :timer.send_interval(5000, :ping)
    send(self, {:after_join, message})

    {:ok, socket}
  end

  def join("rooms:" <> _private_subtopic, _message, _socket) do
    {:error, %{reason: "unauthorized"}}
  end

  def handle_info({:after_join, msg}, socket) do
    broadcast! socket, "user:entered", %{user: msg["user"]}
    push socket, "join", %{status: "connected"}
    {:noreply, socket}
  end
  def handle_info(:ping, socket) do
    push socket, "new:msg", %{user: "SYSTEM", body: "ping"}
    {:noreply, socket}
  end

  def terminate(reason, _socket) do
    Logger.debug"> leave #{inspect reason}"
    :ok
  end

  def handle_in("new:msg", msg, socket) do
    broadcast! socket, "new:msg", %{user: msg["user"], body: msg["body"]}
    {:reply, {:ok, %{msg: msg["body"]}}, assign(socket, :user, msg["user"])}
  end
end

More Repositories

1

render_sync

Real-time Rails Partials
Ruby
1,398
star
2

phoenix_live_view_example

Elixir
534
star
3

todo_trek

Elixir
317
star
4

elixir_express

Elixir
283
star
5

labrador

A loyal data retriever for your Rails development databases.
CSS
254
star
6

atlas

Object Relational Mapper for Elixir
Elixir
214
star
7

mailgun

Elixir Mailgun Client
Elixir
193
star
8

phoenix_haml

Phoenix Template Engine for Haml
Elixir
156
star
9

dot_emacs

evil-mode
Emacs Lisp
94
star
10

single_file_phx_bumblebee_ml

Elixir
91
star
11

elixirconf_training

JavaScript
73
star
12

single_file_phoenix_fly

Elixir
55
star
13

sketchpad

Elixir
42
star
14

channelsac

Ruby
31
star
15

sync_example

Ruby
24
star
16

phoenix_vs_rails_showdown

Ruby
22
star
17

phoenix_presence_example

Elixir
14
star
18

semantic-ui-brunch-phoenix

Elixir
13
star
19

phoenix_brunch_react

Elixir
11
star
20

dot_vim

Vim Script
11
star
21

ex_copter

Elixir client for the Parrot AR 2.0 Quadcopter
Elixir
10
star
22

phoenix_takes_flight

CSS
9
star
23

metrics

Elixir
8
star
24

blinky_presence

Phoenix Presence with Nerves example
Elixir
8
star
25

file_presenter

Elixir
6
star
26

gitit

Introspect project directory and launch browser to github repo page
CoffeeScript
6
star
27

bclose.vim

Delete a buffer without closing the window
Vim Script
6
star
28

riak_tasks

Simple riak cluster bootstrap and management for dev and test environments
Elixir
5
star
29

rumbl-example

Elixir
5
star
30

pubsub_stress

JavaScript
5
star
31

phoenix_brunch_vue

Elixir
5
star
32

phlux

JavaScript
4
star
33

sublime-files

Sublime Text 2 settings and packages
3
star
34

hex_issue_example

Elixir
2
star
35

phoenix_pubsub_federation

Elixir
2
star
36

coffeekup_rails

Ruby
2
star
37

phoenix_render_example

Elixir
2
star
38

phoenix_federation_server

Elixir
2
star
39

fishcakez_channel_example

Elixir
2
star
40

historian

Ruby
1
star
41

validate

Coffeescript client-side validation library
CoffeeScript
1
star
42

dotfiles

Shell
1
star
43

phoenix_debugger_bug

Elixir
1
star
44

riaktor

Coming soon
1
star
45

live_eex

Elixir
1
star
46

my_plug

Elixir
1
star
47

chrismccord.com-old-

JavaScript
1
star