Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building multiplayer game using Reactive Streams

Building multiplayer game using Reactive Streams

This talk introduces streams and reactive streams. You will learn how stream-based programming can be used to implement web frontend and multiplayer backend of the classic game: Snake.

Building dynamic applications using imperative approach tends to create lots of unmaintainable code. Stream-based programming tries to solve this problem by introducing fully declarative way of defining application logic. While using streams, you will focus on what needs to be done, not how and when.

The talk is divided into 3 parts. In the first part you will learn how to create a frontend of the Snake web game using streams as building blocks. Then, we will move to the server side and use Scala and Akka Stream library to create backend service that will allow the game to be played by multiple players. In the third part, we will discuss reactive streams and how they make asynchronous communication safe.

Michał Płachta

February 29, 2016
Tweet

More Decks by Michał Płachta

Other Decks in Programming

Transcript

  1. KSUG / Kraków / 29.02.2016 @miciek Building Multiplayer Game using

    Streams and Reactive Streams Michał Płachta
  2. KSUG / Kraków / 29.02.2016 @miciek Streams? • way of

    defining application logic • focused on data transformations • unbounded collections • have hardcoded time • declarative
  3. KSUG / Kraków / 29.02.2016 @miciek What you will learn?

    • how frontend web app written in streams look like • how backend app written using streams look like • how do Reactive Streams keep our streams safe?
  4. KSUG / Kraków / 29.02.2016 @miciek Stream operators: map &

    scan stream.map(f) • transforms values from stream using function f • returns a new stream with transformed values stream.scan(init, f) • accumulates values from stream using function f ◦ f(acc,val) => new_acc • returns a new stream that outputs accumulator on each new value
  5. KSUG / Kraków / 29.02.2016 @miciek Streams & Operators are

    lazy No elements = I don’t do anything
  6. KSUG / Kraków / 29.02.2016 @miciek Stream operators: filter stream.filter(p)

    • checks each value from stream against the predicate passed as p • returns a new stream that outputs only values that satisfy condition p Already used: • map(f) • scan(init, f(acc, val))
  7. KSUG / Kraków / 29.02.2016 @miciek Stream operators: merge stream.merge(stream2)

    • stream is merged with stream2 • returns a new stream that outputs values from both stream and stream2 as they appear Already used: • map(f) • scan(init, f(acc, val)) • filter(p)
  8. KSUG / Kraków / 29.02.2016 @miciek Stream operators: sampledBy stream.sampledBy(stream2)

    • last value from stream is taken when any value appears in stream2 • returns a new stream that outputs values from stream sampled by values from stream2 Already used: • map(f) • scan(init, f(acc, val)) • filter(p) • merge(stream2)
  9. KSUG / Kraków / 29.02.2016 @miciek Current implementation 10 streams

    • “ticks” • “key presses” • “left key presses” • “right key presses” • “left rotations” • “right rotations” • “actions” • “direction changes” • “directions” • “snake head positions” + map, scan, filter, merge & sampledBy
  10. KSUG / Kraków / 29.02.2016 @miciek Stream operators: slidingWindow stream.slidingWindow(n)

    • aggregate last n values • returns a new stream that outputs arrays of last n values from the stream • can be implemented using scan Already used: • map(f) • scan(init, f(acc, val)) • filter(p) • merge(stream2) • sampledBy(stream2)
  11. KSUG / Kraków / 29.02.2016 @miciek Quiz: Eating a fruit?

    6 operators • map(f) • scan(init, f(acc, val)) • filter(p) • merge(stream2) • sampledBy(stream2) • slidingWindow(n) WHICH STREAMS AND OPERATORS SHOULD WE REUSE TO IMPLEMENT “EATING A FRUIT” FUNCTIONALITY? 11 streams • “ticks” • “key presses” • “left key presses” • “right key presses” • “left rotations” • “right rotations” • “actions” • “direction changes” • “directions” • “snake head positions” • “snakes”
  12. KSUG / Kraków / 29.02.2016 @miciek Snake Server App Requirements

    • client must send snake positions to the server each time it changes • server must generate fruits • server must keep scores • server must broadcast: ◦ positions of all snakes to other players ◦ positions of fruits to all players ◦ current scoreboard to all players
  13. KSUG / Kraków / 29.02.2016 @miciek Crossing Async Boundary Push

    Model • not safe when Subscriber slower • perfect when Subscriber faster Pull Model • too slow when Subscriber faster • perfect when Subscriber slower
  14. KSUG / Kraków / 29.02.2016 @miciek Reactive Streams Streams with

    supply & demand • start in Pull Mode • Consumer asks for elements (= demand) • Publisher goes into Push Mode • supplies elements until demand is satisfied
  15. KSUG / Kraków / 29.02.2016 @miciek Reactive Streams API public

    interface Publisher<T> { public void subscribe(Subscriber<? super T> s); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscription { public void request(long n); public void cancel(); } public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {}
  16. KSUG / Kraków / 29.02.2016 @miciek Simple API, hard implementation...

    https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.0/README.md#specification
  17. KSUG / Kraków / 29.02.2016 @miciek Reactive Streams API implementations

    • Project Reactor • Ratpack • Vert.x • Slick • Akka Stream • JDK 9 • Integrations: ◦ Kafka, ◦ Mongo, ◦ Cassandra
  18. KSUG / Kraków / 29.02.2016 @miciek Akka Stream model Publisher

    => Source Processor => Flow Subscriber => Sink Our Snake implementation uses Reactive Streams!
  19. KSUG / Kraków / 29.02.2016 @miciek • NO ◦ frontend

    is pushing every 100ms • Possible solutions: ◦ Reactive Streams web frameworks? ◦ conflate/expand? ◦ buffer between frontend & backend? Is Snake Multiplayer safe?
  20. KSUG / Kraków / 29.02.2016 @miciek Links github.com/miciek/web-snake-react-bacon Client Side

    Code github.com/miciek/snake-multiplayer-akka-streams Server Side Code rxmarbles.com/ Play with streams and operators! doc.akka.io/docs/akka-stream-and-http-experimental/2.0.3/ Akka Stream baconjs.github.io/ BaconJS - streams in JavaScript
  21. KSUG / Kraków / 29.02.2016 @miciek Building Multiplayer Game using

    Streams and Reactive Streams Michał Płachta www.michalplachta.com THANK YOU!