Robert Pankowecki ???

/home/rupert/Dropbox/drug/wroclawrb/logos/drug-logo-name-rect-sq.png /home/rupert/Dropbox/drug/wroclawrb/krasnal.png /home/rupert/Dropbox/drug/arkency.png /home/rupert/Dropbox/Photos/rupert_outside_bw.jpg

What is Web 3.0 ?

/home/rupert/Dropbox/drug/web3/simpsons_nelson_haha21_429x0.jpg

How do I imagine Web 3.0 ?

Gmail

/home/rupert/Dropbox/drug/web3/gmail.png

Facebook

/home/rupert/Dropbox/drug/web3/fb_stream.png

Facebook

/home/rupert/Dropbox/drug/web3/fb_chat.png

Tweeter

/home/rupert/Dropbox/drug/web3/tweetdeck.png

Trello

/home/rupert/Dropbox/drug/web3/trello.png

In other words…

Just use Websockets

SSE

One reason SSEs have been kept in the shadow is because later APIs like WebSockets provide a richer protocol to perform bi-directional, full-duplex communication. Having a two-way channel is more attractive for things like games, messaging apps, and for cases where you need near real-time updates in both directions. However, in some scenarios data doesn’t need to be sent from the client. You simply need updates from some server action. A few examples would be friends' status updates, stock tickers, news feeds, or other automated data push mechanisms

Example 1 (EM)

Demo (EM)

About Websockets?

Websockets Support

/home/rupert/Dropbox/drug/web3/support.png

Standard ?

~/develop/fun/web3/em-websocket/lib/em-websocket (master) > tree
├── close03.rb
├── close05.rb
├── close06.rb
├── close75.rb
├── connection.rb
├── debugger.rb
├── framing03.rb
├── framing04.rb
├── framing05.rb
├── framing07.rb
├── framing76.rb
├── handler03.rb
├── handler05.rb
├── handler06.rb
├── handler07.rb
├── handler08.rb
├── handler13.rb
├── handler75.rb
├── handler76.rb
├── handler_factory.rb
├── handler.rb
├── handshake04.rb
├── handshake75.rb
├── handshake76.rb
├── masking04.rb
├── message_processor_03.rb
├── message_processor_06.rb
├── version.rb
└── websocket.rb

In my browser:

module EventMachine
  module WebSocket
    class Handler13 < Handler
      include Handshake04
      include Framing07
      include MessageProcessor06
      include Close06
    end
  end
end

Simple ?

def process_data(newdata)
  error = false

  while !error && @data.size >= 2
    pointer = 0

    fin = (@data.getbyte(pointer) & 0b10000000) == 0b10000000
    # Ignoring rsv1-3 for now
    opcode = @data.getbyte(pointer) & 0b00001111
    pointer += 1

    mask = (@data.getbyte(pointer) & 0b10000000) == 0b10000000
    length = @data.getbyte(pointer) & 0b01111111
    pointer += 1

    # raise WebSocketError, 'Data from client must be masked' unless mask

    payload_length = case length
    when 127 # Length defined by 8 bytes
      # Check buffer size
      if @data.getbyte(pointer+8-1) == nil
        debug [:buffer_incomplete, @data]
        error = true
        next
      end

      # Only using the last 4 bytes for now, till I work out how to
      # unpack 8 bytes. I'm sure 4GB frames will do for now :)
      l = @data.getbytes(pointer+4, 4).unpack('N').first
      pointer += 8
      l
    when 126 # Length defined by 2 bytes
      # Check buffer size
      if @data.getbyte(pointer+2-1) == nil
        debug [:buffer_incomplete, @data]
        error = true
        next
      end

      l = @data.getbytes(pointer, 2).unpack('n').first
      pointer += 2
      l
    else
      length
    end

    # Compute the expected frame length
    frame_length = pointer + payload_length
    frame_length += 4 if mask

    if frame_length > @connection.max_frame_size
      raise WSMessageTooBigError, "Frame length too long (#{frame_length} bytes)"
    end

    # Check buffer size
    if @data.getbyte(frame_length - 1) == nil
      debug [:buffer_incomplete, @data]
      error = true
      next
    end

    # Remove frame header
    @data.slice!(0...pointer)
    pointer = 0

    # Read application data (unmasked if required)
    @data.read_mask if mask
    pointer += 4 if mask
    application_data = @data.getbytes(pointer, payload_length)
    pointer += payload_length
    @data.unset_mask if mask

    # Throw away data up to pointer
    @data.slice!(0...pointer)

    frame_type = opcode_to_type(opcode)

    if frame_type == :continuation && !@frame_type
      raise WSProtocolError, 'Continuation frame not expected'
    end

    if !fin
      debug [:moreframe, frame_type, application_data]
      @application_data_buffer << application_data
      # The message type is passed in the first frame
      @frame_type ||= frame_type
    else
      # Message is complete
      if frame_type == :continuation
        @application_data_buffer << application_data
        message(@frame_type, '', @application_data_buffer)
        @application_data_buffer = ''
        @frame_type = nil
      else
        message(frame_type, '', application_data)
      end
    end
  end # end while
end

def send_frame(frame_type, application_data)
  debug [:sending_frame, frame_type, application_data]

  if @state == :closing && data_frame?(frame_type)
    raise WebSocketError, "Cannot send data frame since connection is closing"
  end

  frame = ''

  opcode = type_to_opcode(frame_type)
  byte1 = opcode | 0b10000000 # fin bit set, rsv1-3 are 0
  frame << byte1

  length = application_data.size
  if length <= 125
    byte2 = length # since rsv4 is 0
    frame << byte2
  elsif length < 65536 # write 2 byte length
    frame << 126
    frame << [length].pack('n')
  else # write 8 byte length
    frame << 127
    frame << [length >> 32, length & 0xFFFFFFFF].pack("NN")
  end

  frame << application_data

  @connection.send_data(frame)
end

Handshake

/home/rupert/Dropbox/drug/web3/handshake.png

Example 2 (not EM ??)

Example 2 (not EM ??)

Example 2 (Celluloid::IO)

Demo (Celluloid::IO)

History

SPDY

/home/rupert/Dropbox/drug/web3/advanced_spdy.png