Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions examples/unix-socket/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2019-2025, by Samuel Williams.

require "async"
require "async/http/client"
require "io/endpoint/unix_endpoint"

SOCKET_PATH = "/tmp/falcon-unix-socket-example.sock"
RESPONSE_MAX_SIZE = 1024

def ping_request
# Create a unix socket endpoint
socket = UNIXSocket.new(SOCKET_PATH)

ping_request = [
"GET /ping HTTP/1.1",
"Host: localhost",
"Connection: close",
"",
"",
]

socket.write(ping_request.join("\r\n"))

response = socket.recv(RESPONSE_MAX_SIZE)
puts "Response: #{response}"
end

puts "🚀 Starting client..."
puts "🏓 Sending PING request...\n"
ping_request

while true
print "\nEnter a message to reverse (or 'exit' to quit): "
message = gets

break if message.nil? || message.strip.downcase == "exit"

# Create a unix socket endpoint
socket = UNIXSocket.new(SOCKET_PATH)

reverse_request = [
"POST /reverse HTTP/1.1",
"Host: localhost",
"Content-Length: #{message.bytesize}",
"Connection: close",
"",
message,
]

socket.write(reverse_request.join("\r\n"))

response = socket.recv(1024)
puts "\nResponse: #{response}"
end

puts "👋 Exiting client..."
16 changes: 16 additions & 0 deletions examples/unix-socket/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env falcon --verbose serve -c
# frozen_string_literal: true

run do |env|
# This is not part of the rack specification, but is available when running under Falcon.
request = env["protocol.http.request"]

if request.method == "GET" && env["PATH_INFO"] == "/ping"
[200, {}, ["PONG"]]
elsif request.method == "POST" && env["PATH_INFO"] == "/reverse"
body = request.body.read
[200, {}, [body.reverse]]
else
[404, {}, ["Not Found"]]
end
end
26 changes: 26 additions & 0 deletions examples/unix-socket/falcon.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env falcon-host
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2019-2025, by Samuel Williams.

require "falcon/environment/rack"
require "falcon/environment/supervisor"

SOCKET_PATH = "/tmp/falcon-unix-socket-example.sock"

# Custom service to handle socket cleanup
service "unix-socket" do
include Falcon::Environment::Rack

scheme "http"
protocol {Async::HTTP::Protocol::HTTP}

endpoint do
Falcon::ProxyEndpoint.unix(
SOCKET_PATH,
scheme: scheme,
protocol: protocol,
)
end
end
72 changes: 72 additions & 0 deletions examples/unix-socket/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Unix Socket Example

This example demonstrates how to run a Falcon server using Unix domain sockets for communication instead of TCP sockets. Unix sockets provide faster inter-process communication when both client and server are on the same machine, with lower latency and higher throughput compared to TCP sockets.

## Overview

The example includes:
- A Falcon server that listens on a Unix socket at `/tmp/falcon-unix-socket-example.sock`
- Two HTTP endpoints: `/ping` (GET) and `/reverse` (POST)
- A Ruby client that demonstrates both endpoints with interactive messaging

## Usage

### 1. Start the Server

Run the Falcon server using the Unix socket configuration:

```bash
$ bundle exec falcon host falcon.rb
```

The server will create a Unix socket at `/tmp/falcon-unix-socket-example.sock` and listen for connections.

### 2. Run the Client

In a separate terminal, run the client:

```bash
$ ruby client.rb
```

The client will:
1. Send a ping request to test connectivity
2. Prompt you to enter messages that will be reversed by the server
3. Display the server responses

### 3. Example Session

```
🚀 Starting client...
🏓 Sending PING request...

Response: HTTP/1.1 200 OK
Connection: close
Content-Length: 4

PONG

Enter a message to reverse (or 'exit' to quit): Hello Falcon!

Response: HTTP/1.1 200 OK
Connection: close
Content-Length: 13

!noclaF olleH

Enter a message to reverse (or 'exit' to quit): exit
👋 Exiting client...
```

## API Endpoints

### GET `/ping`
- **Description**: Health check endpoint
- **Response**: Returns "PONG" with 200 status
- **Example**: `curl --unix-socket /tmp/falcon-unix-socket-example.sock http://localhost/ping`

### POST `/reverse`
- **Description**: Reverses the request body content
- **Request Body**: Any text content
- **Response**: The reversed text
- **Example**: `curl --unix-socket /tmp/falcon-unix-socket-example.sock -X POST -d "Hello" http://localhost/reverse`
Loading