Streams instead of callbacks

Add streams (push streams for the moment, not reactive streams), and replace some of the event listeners with them.

This enables a new style of protocol parsing:

```ruby
data_chunk_stream = connection.to_stream
line_stream = data_chunk_stream.aggregate(ByteBuffer.new) do |chunk, downstream, buffer|
  buffer << chunk
  while (newline_index = buffer.index("\n"))
    downstream << buffer.read(newline_index + 1)
  end
  buffer
end
request_stream = line_stream.aggregate([]) do |line, downstream, lines|
  # aggregate lines together into requests
end
request_stream.each do |request|
  response = … # process request
  connection.write(response.to_bytes)
end
```