Engineering Computing

PI: Laboratory 7: Networking

Overview

This week's laboratory explores the basics of networked communication. In addition, threading and the listener model play significant roles. Finally, this lab provides an opportunity for you to return to some of your previous code. In this lab, you will implement a networked version of your breakout game from laboratory 5.

Pre-lab

In order to complete this lab, you will need to be familiar with several ideas that we have covered in recent weeks. This prelab reviews many of those concepts. You should bring to lab written answers to each of the questions marked with a Q in this prelab assignment.
  • Listeners

    By now, you should be familiar with the Button <-> ActionListener relationship. In a similar fashion, the breakout code has a World <-> WorldListener relationship: Changes made in the World result in WorldEvent's being sent to registered listeners.

    Q: Using the javadoc linked above, answer the following questions (in writing for your prelab):

    • What methods must a WorldListener implement?
    • What information does a WorldEvent contain?
    • What interface does WorldEvent implement?
    • If ears is a WorldListener and globe is a World, how would you set up ears to listen for changes to globe?
  • Wires

    You will also need to understand how to use the cs101.net.Wire interface and its implementing classes cs101.net.ServerWire and cs101.net.ClientWire. You will be creating your Wires in a slightly different way from what we did in class.

    Q: Look carefully at the two Wire classes. A Wire can be built in several ways. Write a short piece of code that uses one of the cs101 Wire classes (which one?) to send the string "hello" to host 10.40.27.4 on port 4321 without ever prompting the user for the host and port. (This code won't actually run because nothing's running on 10.40.27.4 to receive your string)

    Q:

    • cs101.net.Wires are actually hiding java.io.ObjectOutputStreams. What are the requirements on Objects that may be sent (and thus read) by ObjectOutputStream?
    • What objects do you know satisfy this property? Any in breakout?

Finally, read through the lab assignment below and come to lab ready to build your lab OR full of questions about what you don't understand. Also, please be sure to bring your written check-in questions (answers to everything marked with a Q above) and your working breakout code from that previous lab.

Laboratory

We're going to invent the game of networked breakout. The game will be a cooperative venture between players to demolish all the bricks. To accomplish this, we'll start with 2 working single-player breakout games and connect them so that they can share balls. To simplify the network interaction, all bricks on "the other side" will be rendered as a default "Unknown" brick and the balls will only be rendered when they are on "your side". The local ("your") board is located on the bottom and the remote ("the other side") board is upside-down. labelled sample networked game board
Below are a pair of screen shots showing actual gameplay.

Note the ball crossover occuring.

Tasks

  1. Get network settings
    First, you will need to change the way that you start your breakout game. Last time, you started the program off with a main method that simply creates a GameFrame using that class's no-args constructor. Now, you will have to use a different constructor that takes a NetworkSettings object. (Don't worry, Ben's built the NetworkSettings for you. You just need to use it.)

    You'll want to look at the javadoc for NetworkSettings so you understand how to get the user's selection out of it.

    Now, instead of constructing your GameFrame in main using the no argument constructor, build an instance of NetworkSettings, getSettings() it to get the settings from the user, and pass this object to the GameFrame constructor.

  2. Create a StudentConnector
    Unfortunately, you can't compile and run your code yet. The GameFrame constructor will attempt to create a breakout.StudentConnector object, and you haven't written this yet. A StudentConnector must implement Connector and have a constructor with the following signature:
    public StudentConnector(World local, World remote,
    NetworkSettings settings)
    Write something that just barely compiles. (What methods?) Test it and let us know that you've gotten this far.
  3. WorldListener-izing
    Instead of jumping directly into the network bits, let's first arrange to find out what's happening in the game. Update your StudentConnector to implement WorldListener and have it register itself as a listener on the "local" world during StudentConnector's constructor. This way it'll find out when the player loads a board, breaks bricks, or has a ball leave the board. Have your code print out something when these events occur. Test it.
  4. Wiring up
    Implement a connect() method for StudentConnector. Based on the NetworkSettings passed to the constructor, build an appropriate Wire with the correct parameters. isConnected should return true if the connection succeeds.
  5. Sending events
    Update the WorldListener methods to send along the event data over the Wire. Remember only to attempt to send if you're connected. Failures in sending should signal that you aren't actually connected. These methods should be very simple (solutions are ~6 lines long each).
  6. Receiving events
    When the connect button on the GameFrame is clicked, your StudentConnector's connect() is called. Your connect() method should attempt to connect with the given network settings. It should create a new Thread to read incoming events from the network. One way to accomplish this is to have StudentConnector also implement Runnable. Implement a read-loop that just prints out the events it receives. Start up the read-loop when you've successfuly connected. Any communication failure means that you aren't really connected. Together with your code from the previous task, you should be able to test and see if the two programs are communicating.
  7. Doing the Right Thing
    Now, think about handling different events in different ways.
    • ADD_BRICK events from the network should result adding an OtherBrick to the remote world.
    • REMOVE_BRICK events should result in removing a brick at the given location.
    • BALL_TRANSFER events should cause a new SimpleBall to be added to the local world (use this constructor). The supplied direction is incorrect (it's pointing in the wrong Y direction), and the position needs to be mirrored on the X axis, and slightly offset from the top of the board (so as to avoid it immediately crossing back over).

    However, just adding these will result in concurrency problems! The network thread handling the above events can interfere with the object and rendering threads of the game. In order to avoid this problem, the locking discipline for Breakout is to acquire a lock on a World before interacting with it. In plain terms, your code must enter a synchronized (World) block before calling any methods on the World. The synchronized block waits until it acquires a lock on the given object before proceeding. Which world you synchronize on (local or remote) depends on which one you are working with at the time.

    Do NOT synchronize outside your while (true) loop or have the synchronized block include reading from the network! The board won't display while the network code holds the lock on a World!

The target exercise is to have a working net breakout game.

As extra gravy, try implementing the networking pieces without using Wires.

If you are still looking for more, you can always network your Scribbles (according to the Shared Whiteboard assignment on the cs101 site).

Post-lab

Your completed assignment should include:

  • on the front page, how much out-of-class time (approximately) you've spent on reading, on preparation of the homework, in lab, and on other non-class-time course-related activities (and what). These times should include work from last Wednesday 5pm to this Wednesday at 5pm
  • your code and a description of its functionality.
  • documentation of your code. (This can be inside the code.)
  • your observations concerning
  • a brief description of the check-out interaction, and answers to any specific issues s/he may have asked you to address.
  • the names and roles of any collaborators in any parts of the project.
  • a brief status update on how your final project is coming.
  • the coolest thing you've heard this week (not necessarily pi-related)

Lab assignments are due on Wednesdays at 5pm. They may, of course, be turned in earlier.

Questions, comments, gripes and other communication to pi-staff@lists.cognition.olin.edu
This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the Computers and Cognition Laboratory and the Electrical and Computer Engineering area at Franklin W. Olin College of Engineering. Olin College Logo