Created
February 2, 2020 16:33
-
-
Save Prigin/7ba5724b0987021f3e0c0adfa2837af6 to your computer and use it in GitHub Desktop.
mkdev
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: false | |
require 'socket' | |
class Server | |
attr_reader :queue | |
Struct.new('Connection', :nick, :sock, :rcv_thr) | |
def initialize(log, addr = 'localhost', port = 3000) | |
addr.to_s | |
@srv_sock = TCPServer.new(addr, port) | |
@srv_sock.listen(2) | |
@queue = Queue.new | |
@log = log ################################################################################# | |
@conn_list = [] | |
@loops = [Thread.new { master_loop }, Thread.new { accept_loop }] | |
end | |
def accept_loop | |
loop do | |
conn = @srv_sock.accept | |
nick = conn.gets.chomp | |
rcv_thr = Thread.new { rcv_loop(conn, nick) } | |
@queue << [:conn_new, Struct::Connection.new(nick, conn, rcv_thr)] | |
end | |
end | |
def rcv_loop(sock, nick) | |
begin | |
loop do | |
msg = sock.gets.chomp | |
@queue << [:log, "#{nick}: #{msg}"] | |
@queue << [:send_all, [msg, nick]] | |
end | |
rescue StandardError | |
@queue << [:disconnect, nick] | |
end | |
end | |
def master_loop | |
loop do | |
tag, obj = @queue.deq | |
case tag | |
when :send_all | |
send_all(obj.first, obj.last) | |
when :log | |
@log.write obj | |
when :conn_new | |
@conn_list << obj | |
when :disconnect | |
disconnect(obj) | |
end | |
end | |
end | |
def send_all(msg, nick = nil) | |
@conn_list.each do |conn| | |
msg = "#{nick}: #{msg}" if nick | |
conn.sock.puts(msg) unless conn.nick == nick | |
end | |
end | |
def disconnect(nick) | |
@conn_list.delete_if do |conn| | |
if conn.nick == nick | |
conn.rcv_thr.kill | |
conn.sock.close | |
true | |
end | |
end | |
end | |
end | |
class LogWriter ######################################################################################## | |
def initialize(log, container, marker = :_data) | |
@container = container # [] | |
@log = log | |
@index = container.index(marker) | |
end | |
def write(str) | |
@container[@index] = str | |
@log << @container | |
end | |
end | |
class Screen | |
attr_accessor :queue | |
def initialize(hsh) | |
@scr_objects = hsh | |
@queue = Queue.new | |
@loop = Thread.new { update } | |
end | |
def update | |
loop do | |
obj, str = @queue.deq | |
@scr_objects[obj].push(str) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment