class Protocol::WebSocket::Connection

Attributes

framer[R]

The framer which is used for reading and writing frames.

frames[RW]

Buffered frames which form part of a complete message.

mask[R]

The (optional) mask which is used when generating frames.

Public Class Methods

new(framer, mask: nil) click to toggle source

@parameter mask [String] 4-byte mask to be used for frames generated by this connection.

# File lib/protocol/websocket/connection.rb, line 28
def initialize(framer, mask: nil)
        @framer = framer
        @mask = mask
        
        @state = :open
        @frames = []
end

Public Instance Methods

close() click to toggle source
# File lib/protocol/websocket/connection.rb, line 53
def close
        send_close unless closed?
        
        @framer.close
end
closed?() click to toggle source
# File lib/protocol/websocket/connection.rb, line 49
def closed?
        @state == :closed
end
flush() click to toggle source
# File lib/protocol/websocket/connection.rb, line 45
def flush
        @framer.flush
end
next_message() click to toggle source

Deprecated.

# File lib/protocol/websocket/connection.rb, line 203
def next_message
        @framer.flush
        
        while read_frame
                if @frames.last&.finished?
                        frames = @frames
                        @frames = []
                        
                        return frames
                end
        end
end
open!() click to toggle source
# File lib/protocol/websocket/connection.rb, line 154
def open!
        @state = :open
        
        return self
end
read() click to toggle source

@return [String] a unicode or binary string.

# File lib/protocol/websocket/connection.rb, line 189
def read
        @framer.flush
        
        while read_frame
                if @frames.last&.finished?
                        buffer = @frames.map(&:unpack).join
                        @frames = []
                        
                        return buffer
                end
        end
end
read_frame() { |frame| ... } click to toggle source
# File lib/protocol/websocket/connection.rb, line 59
def read_frame
        return nil if closed?
        
        frame = @framer.read_frame
        
        yield frame if block_given?
        
        frame.apply(self)
        
        return frame
rescue ProtocolError => error
        send_close(error.code, error.message)
        
        raise
rescue
        send_close(Error::PROTOCOL_ERROR, $!.message)
        
        raise
end
receive_binary(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 93
def receive_binary(frame)
        if @frames.empty?
                @frames << frame
        else
                raise ProtocolError, "Received binary, but expecting continuation!"
        end
end
receive_close(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 133
def receive_close(frame)
        @state = :closed
        
        code, message = frame.unpack
        
        if code and code != Error::NO_ERROR
                raise ClosedError.new message, code
        end
end
receive_continuation(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 101
def receive_continuation(frame)
        if @frames.any?
                @frames << frame
        else
                raise ProtocolError, "Received unexpected continuation!"
        end
end
receive_frame(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 172
def receive_frame(frame)
        warn "Unhandled frame #{frame.inspect}"
end
receive_ping(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 160
def receive_ping(frame)
        if @state != :closed
                write_frame(frame.reply(mask: @mask))
        else
                raise ProtocolError, "Cannot receive ping in state #{@state}"
        end
end
receive_pong(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 168
def receive_pong(frame)
        # Ignore.
end
receive_text(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 85
def receive_text(frame)
        if @frames.empty?
                @frames << frame
        else
                raise ProtocolError, "Received text, but expecting continuation!"
        end
end
send_binary(buffer) click to toggle source
# File lib/protocol/websocket/connection.rb, line 116
def send_binary(buffer)
        frame = BinaryFrame.new(mask: @mask)
        frame.pack buffer
        
        write_frame(frame)
end
send_close(code = Error::NO_ERROR, message = nil) click to toggle source
# File lib/protocol/websocket/connection.rb, line 123
def send_close(code = Error::NO_ERROR, message = nil)
        frame = CloseFrame.new(mask: @mask)
        frame.pack(code, message)
        
        self.write_frame(frame)
        self.flush
        
        @state = :closed
end
send_ping(data = "") click to toggle source
# File lib/protocol/websocket/connection.rb, line 143
def send_ping(data = "")
        if @state != :closed
                frame = PingFrame.new(mask: @mask)
                frame.pack(data)
                
                write_frame(frame)
        else
                raise ProtocolError, "Cannot send ping in state #{@state}"
        end
end
send_text(buffer) click to toggle source
# File lib/protocol/websocket/connection.rb, line 109
def send_text(buffer)
        frame = TextFrame.new(mask: @mask)
        frame.pack buffer
        
        write_frame(frame)
end
write(buffer) click to toggle source

@param buffer [String] a unicode or binary string.

# File lib/protocol/websocket/connection.rb, line 177
def write(buffer)
        # https://tools.ietf.org/html/rfc6455#section-5.6
        
        # Text: The "Payload data" is text data encoded as UTF-8
        if buffer.encoding == Encoding::UTF_8
                send_text(buffer)
        else
                send_binary(buffer)
        end
end
write_frame(frame) click to toggle source
# File lib/protocol/websocket/connection.rb, line 79
def write_frame(frame)
        @framer.write_frame(frame)
        
        return frame
end