Class: WebSocket::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/local_server.rb

Instance Method Summary collapse

Constructor Details

#initialize(host: 'localhost', port: nil) ⇒ Server

Returns a new instance of Server.



42
43
44
# File 'lib/local_server.rb', line 42

def initialize(host: 'localhost', port: nil)
  @server, @rd_pipe, @wr_pipe = TCPServer.new(host, port), *IO.pipe
end

Instance Method Details

#broadcast(message) ⇒ Object



46
47
48
# File 'lib/local_server.rb', line 46

def broadcast(message)
  @wr_pipe.puts(message)
end

#shutdownObject



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/local_server.rb', line 50

def shutdown
  broadcast('shutdown')

  @wr_pipe.close
  @wr_pipe = nil

  @thread.join

  @server.close
  @server = nil
end

#startObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/local_server.rb', line 62

def start
  @thread = Thread.new do
    connections = []
    running = true
    while running
      rs, _, _ = IO.select([ @server, @rd_pipe, *connections.map { |conn| conn.socket } ])
      rs.each do |socket|
        if socket == @server
          socket = @server.accept
          begin
            connections << Connection.establish(socket)
          rescue => e
            $log.warn("Failed to perform handshake with new WebSocket client: #{e}", e)
            socket.close
          end
        elsif socket == @rd_pipe
          message = @rd_pipe.gets.chomp
          if message == 'shutdown'
            running = false
            break
          end
          $log.debug("Send ‘#{message}’ to #{connections.count} WebSocket #{connections.count == 1 ? 'client' : 'clients'}") unless connections.empty?
          connections.each do |conn|
            begin
              conn.puts(message)
            rescue => e
              $log.warn("Error writing to WebSocket client socket: #{e}")
            end
          end
        else
          if conn = connections.find { |candidate| candidate.socket == socket }
            begin
              conn.each_message do |frame|
                $log.debug("Received #{frame.to_s.size} bytes from WebSocket client: #{frame}") unless frame.to_s.empty?
              end
            rescue IO::WaitReadable
              $log.warn("IO::WaitReadable exception while reading from WebSocket client")
            rescue EOFError
              conn.socket.close
              connections.delete(conn)
            end
          end
        end
      end
    end
    @rd_pipe.close
    @rd_pipe = nil
  end
end