Skip to content

Instantly share code, notes, and snippets.

@akoskovacs
Last active September 13, 2023 22:38
Show Gist options
  • Save akoskovacs/4165376 to your computer and use it in GitHub Desktop.
Save akoskovacs/4165376 to your computer and use it in GitHub Desktop.
Ruby chat server
#!/usr/bin/env ruby
# Run with
# $ chmod +x chat.rb && ./chat.rb
# or
# $ ruby chat.rb
require 'socket'
require 'thread'
class User
attr_accessor :name, :socket, :thread
def initialize(name, socket, thread)
@name = name
@socket = socket
@thread = thread
end
end
$users = []
$users_mutex = Mutex.new
PORT = 4625
server = TCPServer.new PORT
puts "[#{Time.now}]: Server started...\nListening on port #{PORT}\n"
loop do
Thread.start(server.accept) do |client|
client.puts "Welcome to AkChat!"
client.puts "Please login!\n"
client.write "Login: "
username = client.gets.chomp
u = User.new(username, client, Thread.current)
$users_mutex.synchronize do
$users.each do |us|
if us.name == username
client.puts "This username is already taken."
client.close
Thread.stop
else
us.socket.puts "\n### #{username} joined to the conversation ###"
us.socket.write "[#{us.name}]: "
end
end
$users << u
client.puts "Welcome aboard #{username}!"
puts "[#{Time.now}]: User #{username} signed in..."
if ($users.count > 1)
client.puts "We have #{$users.count} users logged in:"
$users.each do |us|
client.puts "\t#{us.name}"
end
end
end
loop do
client.write "[#{username}]: "
msg = client.readline.chomp
if (msg == "quit" || msg == "q")
$users_mutex.synchronize do
$users -= [u]
end
client.close
puts "[#{Time.now}]: #{username} quited from chat"
$users_mutex.synchronize do
$users.each do |us|
us.socket.puts "\n### #{username} quited from the conversation ###"
us.socket.write "[#{us.name}]: "
end
end
Thread.kill(Thread.current)
end
$users_mutex.synchronize do
$users.each do |us|
if (us.name != username)
puts "[#{Time.now}]: Broadcasting message '#{msg}' from #{username} to #{us.name}."
us.socket.puts "\n[#{username}]: #{msg}"
us.socket.write "[#{us.name}]: "
end
end
end
end
end
end
@akoskovacs
Copy link
Author

Connect to the server, (assuming that the PORT is not changed and the server running on the local machine)
$ nc localhost 4625
or
$telnet localhost 4625

@Killua99x
Copy link

@akoskovacs sorry, i like it, have you created a client in ruby to login?

@akoskovacs
Copy link
Author

akoskovacs commented Aug 31, 2016

@KilluaEnki No. There is no need for that. You can use nc (netcat) or telnet (not tested this, just a guess).

@akoskovacs
Copy link
Author

@KilluaEnki Although, it would be easy to implement. Just gets() from the terminal -> write it to socket, read from the socket -> puts() to the terminal.

@aleksandurg98
Copy link

could anyone help me how to write the code for the game wheel of fortune?

@arunth98
Copy link

arunth98 commented Apr 2, 2019

njnj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment