Skip to content

Instantly share code, notes, and snippets.

@collindonnell
Created July 15, 2023 02:42
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save collindonnell/92955cfdd8078b0411db8e717561921f to your computer and use it in GitHub Desktop.
Save collindonnell/92955cfdd8078b0411db8e717561921f to your computer and use it in GitHub Desktop.
Simple Ruby TCP multi-user chat room
#!/usr/bin/env ruby
# frozen_string_literal: true
require "socket"
class Connection
def initialize(client:, server:)
@client = client
@server = server
end
def ask_for_name
send_to_client("What is your name?")
@name = receive_from_client
ask_for_name if @name.nil? || @name.empty?
send_to_client("Welcome #{@name}!") unless @name&.empty?
end
def run
ask_for_name if @name.nil? || @name.empty?
while (line = receive_from_client)
puts "received: #{line}"
if line =~ /quit/i
@client.close
@server.delete_connection(self)
break
end
@server.broadcast(sender: self, line: "#{@name}: #{line}")
end
end
def send_to_client(line)
@client.puts(line)
end
def receive_from_client
@client.gets.chomp
end
end
class Server
def initialize(port)
@server = TCPServer.new(port)
@connections = []
puts "server started on port #{port}"
accept_connections
end
def accept_connections
Thread.new(@server.accept) do |client|
connection = Connection.new(client:, server: self)
@connections << connection
puts "accepted connection from #{client}"
connection.run
end
end
def broadcast(sender:, line:)
@connections.each do |connection|
connection.send_to_client(line) unless connection == sender
end
end
def delete_connection(connection)
@connections.delete(connection)
end
end
server = Server.new(2000)
loop do
server.accept_connections
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment