Here’s how you can build a real-time chat API with Sinatra and Ruby, and connect it to an HTML GUI using JavaScript:
First, you’ll need to install the faye-websocket
gem, which provides support for web sockets in Ruby. You can do this by adding the following line to your Gemfile
and running bundle install
:
gem 'faye-websocket'
Next, you’ll need to set up a web socket server in your Sinatra application. You can do this by creating a new route that listens for web socket connections and sends messages to connected clients when they arrive:
require 'sinatra'
require 'faye/websocket'
require 'sequel' # or whichever database library you're using
DB = Sequel.connect('postgres://localhost/my_database') # replace with your own database connection details
# You might also want to set up your database tables here, if you don't have them already
DB.create_table? :messages do
primary_key :id
String :sender
String :recipient
String :text
Time :timestamp
end
get '/websocket' do
if Faye::WebSocket.websocket?(request.env)
ws = Faye::WebSocket.new(request.env)
ws.on :open do |event|
puts 'Web socket connection opened'
# You might want to store the client's connection in a list here, so you can send messages to it later
end
ws.on :message do |event|
puts "Received message: #{event.data}"
data = JSON.parse(event.data)
sender = data['sender']
recipient = data['recipient']
text = data['text']
timestamp = Time.now
message_id = DB[:messages].insert(sender: sender, recipient: recipient, text: text, timestamp: timestamp)
# You can process the message here and then send it to all connected clients using the following line:
ws.send({ message_id: message_id, sender: sender, recipient: recipient, text: text, timestamp: timestamp }.to_json)
end
ws.on :close do |event|
puts 'Web socket connection closed'
# You might want to remove the client's connection from your list here
end
ws.rack_response
end
end
Next, you can create an HTML GUI for your chat application. This could include a form for sending messages and a list or chat window to display received messages. Here’s an example of what this might look like:
<form id="message-form">
<input type="text" id="sender" placeholder="Your name">
<input type="text" id="recipient" placeholder="Recipient's name">
<input type="text" id="text" placeholder="Type your message here">
<button type="submit">Send</button>
</form>
<ul id="messages"></ul>
You’ll also need to include a script tag to reference your JavaScript file, where you’ll handle the web socket connection and message handling:
const socket = new WebSocket('ws://localhost:4567/websocket');
const messageForm = document.getElementById('message-form');
const messagesList = document.getElementById('messages');
socket.onopen = function(event) {
console.log('Web socket connection opened');
};
socket.onmessage = function(event) {
console.log(`Received message: ${event.data}`);
const messageData = JSON.parse(event.data);
const messageItem = document.createElement('li');
messageItem.innerHTML = `${messageData.sender}: ${messageData.text}`;
messagesList.appendChild(messageItem);
};
socket.onclose = function(event) {
console.log('Web socket connection closed');
// You might want to reconnect to the server here
};
messageForm.addEventListener('submit', event => {
event.preventDefault();
const sender = document.getElementById('sender').value;
const recipient = document.getElementById('recipient').value;
const text = document.getElementById('text').value;
socket.send(JSON.stringify({ sender: sender, recipient: recipient, text: text }));
});
With this setup, you can now send and receive real-time chat messages between the server and the client using web sockets, and display them in the HTML GUI.
To import a JavaScript file into an HTML document, you can use the script
tag and specify the path to the file in the src
attribute. Here’s an example of how you might do this:
<script src="path/to/your/javascript/file.js"></script>
Alternatively, you can also include the JavaScript code directly in the HTML file by placing it inside a script
tag without a src
attribute:
<script>
// Your JavaScript code goes here
</script>
It’s generally a good idea to keep your JavaScript code in separate files to keep your HTML clean and organized, but the inline method can be useful for smaller scripts or when you want to include the code in a specific part of the HTML document.