Implementing WebSockets With Elixir and Phoenix Framework

Implementing WebSockets With Elixir and Phoenix Framework

WebSockets have become a crucial part of modern web applications, enabling real-time communication between clients and servers. In this article, we'll explore how to implement WebSockets using the Elixir programming language and the Phoenix framework, which is known for its high-performance capabilities and scalability.

What is WebSocket?

WebSockets are a protocol that allows for full-duplex communication channels over a single TCP connection. Unlike traditional HTTP requests, which are request-response based, WebSockets enable continuous data streams, making them ideal for applications that require real-time updates, such as chat applications, online gaming, and live notifications.

Setting Up Your Phoenix Application

Before diving into WebSocket implementation, ensure you have Elixir and Phoenix installed on your machine. If you haven't set up a Phoenix project yet, you can create one using the following command:

mix phx.new my_app --no-ecto

Navigate to your project directory:

cd my_app

Adding WebSocket Support to Your Phoenix App

To implement WebSockets, you need to define a WebSocket channel. First, generate a channel by running:

mix phx.gen.channel Topic

This command will create a new channel module in the `lib/my_app_web/channels` directory. Open the newly created file and modify the `join` function to handle joining the channel:

defmodule MyAppWeb.TopicChannel do
  use MyAppWeb, :channel
def join("topic:lobby", _message, socket) do
    {:ok, socket}
  end
def handle_in("new_msg", %{"body" => body}, socket) do
    broadcast!(socket, "new_msg", %{body: body})
    {:noreply, socket}
  end
end

Configuring the Endpoint

The next step involves updating your endpoint configuration to enable WebSocket connections. Locate the `lib/my_app_web/endpoint.ex` file and ensure the following line is uncommented:

socket "/socket", MyAppWeb.UserSocket

You also need to create the UserSocket module, which defines how users can connect to different channels:

defmodule MyAppWeb.UserSocket do
  use Phoenix.Socket
channel "topic:*", MyAppWeb.TopicChannel
def connect(_params, socket, _connect_info) do
    {:ok, socket}
  end
def id(_socket), do: nil
end

Frontend WebSocket Connection

Now that the backend is set up, it's time to implement the WebSocket connection on the client-side. In your HTML file, include the Phoenix JavaScript library:

<script src="/js/phoenix.js"></script>

Then, create a connection to the WebSocket in a separate JavaScript file. Use the following code block:

import { Socket } from "phoenix"
let socket = new Socket("/socket", {params: {userToken: "123"}})
socket.connect()
let channel = socket.channel("topic:lobby", {})
channel.join()
  .receive("ok", resp => { console.log("Joined successfully", resp) })
  .receive("error", resp => { console.log("Unable to join", resp) })
channel.on("new_msg", payload => {
  console.log("Received new message:", payload.body)
})
document.getElementById("send_message").addEventListener("click", () => {
  let input = document.getElementById("message_input").value
  channel.push("new_msg", {body: input})
  document.getElementById("message_input").value = ""
})

Testing Your WebSockets

Now that everything is set up, you can start your Phoenix server:

mix phx.server

Open your browser and navigate to the appropriate URL (typically http://localhost:4000). Test sending and receiving messages to verify that your WebSockets are working as expected.

Conclusion

Implementing WebSockets in an Elixir and Phoenix application allows you to build real-time features that enhance user experience significantly. With the ability to manage concurrent users and scale effortlessly, Phoenix and