Lobby Example
This code example demonstrates how to create a typical multiuser lobby with Reactor. The lobby shows a room list that includes the number of users in each room, and provides a way to join and leave rooms.
Here's what the lobby looks like (try opening it in several browser windows if you want to see the effect of joining and leaving the rooms in the lobby):
Note: this example focuses on the Reactor API, and therefore shows only the bare minimum code required to create a lobby user interface.
The Code
Here's the code for the lobby:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; import net.user1.logger.Logger; import net.user1.reactor.*; // A simple Union example application showing how to build a basic // lobby with Reactor. public class UnionLobby extends Sprite { protected var reactor:Reactor; protected var roomList:TextField; protected var joinRoomA:TextField; protected var leaveRoomA:TextField; protected var createTestRoom:TextField; protected var removeTestRoom:TextField; protected var testRoomID:String; // Constructor. public function UnionLobby () { // Create the interface. createUI(); // Create the Reactor object and connect to Union. reactor = new Reactor(); reactor.getLog().setLevel(Logger.DEBUG); reactor.addEventListener(ReactorEvent.READY, readyListener); reactor.connect("tryunion.com", 80); } // Event listener triggered when the connection is ready. protected function readyListener (e:ReactorEvent):void { // Ask to be notified when a room with the qualifier "lobbyexample" is // added to or removed from the server. In response to this // watchForRooms() call, the RoomManager will trigger // RoomManagerEvent.ROOM_ADDED and RoomManagerEvent.ROOM_REMOVED events. reactor.getRoomManager().watchForRooms("lobbyexample"); // Register for the RoomManagerEvent.ROOM_ADDED and // RoomManagerEvent.ROOM_REMOVED events. reactor.getRoomManager().addEventListener(RoomManagerEvent.ROOM_ADDED, roomAddedListener); reactor.getRoomManager().addEventListener(RoomManagerEvent.ROOM_REMOVED, roomRemovedListener); // Create three example rooms that will appear in the lobby. Use a // RoomSettings object to specify that the rooms should not // "die on empty"; otherwise, each room would automatically be removed // when its last occupant leaves. var roomSettings:RoomSettings = new RoomSettings(); roomSettings.removeOnEmpty = false; reactor.getRoomManager().createRoom("lobbyexample.roomA", roomSettings); reactor.getRoomManager().createRoom("lobbyexample.roomB", roomSettings); reactor.getRoomManager().createRoom("lobbyexample.roomC", roomSettings); } // Event listener triggered when a room is added to the // room manager's room list. protected function roomAddedListener (e:RoomManagerEvent):void { // There's a new room, so update the on-screen room list. updateRoomList(); // Ask to be notified when the new room's client-count changes. Once the // room is observed, if other clients join the room, this client will // be notified. UpdateLevel values specify how much information this // client should be told about the room. This is a lobby, so we want // the room's occupant count only. var updateLevels:UpdateLevels = new UpdateLevels(); updateLevels.clearAll(); updateLevels.occupantCount = true; e.getRoom().observe(null, updateLevels); // Register to be notified any time the new room's client count changes. e.getRoom().addEventListener(RoomEvent.OCCUPANT_COUNT, roomClientCountListener); } // Event listener triggered when a room is removed from the // room manager's room list. protected function roomRemovedListener (e:RoomManagerEvent):void { // A room is gone, so update the on-screen room list. updateRoomList(); } // The number of clients in one of the rooms changed, so update // the on-screen room list to show the new client count. protected function roomClientCountListener (e:RoomEvent):void { updateRoomList(); } // Display the list of rooms in a text field. protected function updateRoomList ():void { roomList.text = ""; for each (var room:Room in reactor.getRoomManager().getRoomsWithQualifier("lobbyexample")) { roomList.appendText(room.getRoomID() + " (" + room.getNumOccupants() + ")\n"); } } // Join-Room button click listener. protected function joinRoomAClickListener (e:MouseEvent):void { var roomA:Room = reactor.getRoomManager().getRoom("lobbyexample.roomA"); if (roomA != null) { roomA.join(); } } // Leave-Room button click listener. protected function leaveRoomAClickListener (e:MouseEvent):void { var roomA:Room = reactor.getRoomManager().getRoom("lobbyexample.roomA"); if (roomA != null) { roomA.leave(); } } // Create-Room button click listener. protected function createTestRoomClickListener (e:MouseEvent):void { // Create a new test room with a random room id. By default, a client that // creates a room is granted permission to remove that room, so this client // will be allowed to remove the test room. Room-removal permissions // can be configured in Union Server's union.xml configuration file. testRoomID = testRoomID || ("lobbyexample.test" + Math.floor((Math.random()*100000)).toString()); var roomSettings:RoomSettings = new RoomSettings(); roomSettings.removeOnEmpty = false; reactor.getRoomManager().createRoom(testRoomID, roomSettings); } // Remove-Room button click listener. protected function removeTestRoomClickListener (e:MouseEvent):void { var testRoom:Room = reactor.getRoomManager().getRoom(testRoomID); if (testRoom != null) { testRoom.remove(); } } // Create the user interface protected function createUI ():void { // A text field for the room list roomList = new TextField(); roomList.background = true; roomList.border = true; roomList.x = 150; roomList.y = 20; roomList.width = 150; roomList.height = 100; addChild(roomList); // The join-room button joinRoomA = new TextField(); joinRoomA.selectable = false; joinRoomA.background = true; joinRoomA.border = true; joinRoomA.x = 180; joinRoomA.y = 130; joinRoomA.width = 90; joinRoomA.height = 20; joinRoomA.text = "Join Room A"; joinRoomA.addEventListener(MouseEvent.CLICK, joinRoomAClickListener); addChild(joinRoomA); // The leave-room button leaveRoomA = new TextField(); leaveRoomA.selectable = false; leaveRoomA.background = true; leaveRoomA.border = true; leaveRoomA.x = 180; leaveRoomA.y = 160; leaveRoomA.width = 90; leaveRoomA.height = 20; leaveRoomA.text = "Leave Room A"; leaveRoomA.addEventListener(MouseEvent.CLICK, leaveRoomAClickListener); addChild(leaveRoomA); // The create-room button createTestRoom = new TextField(); createTestRoom.selectable = false; createTestRoom.background = true; createTestRoom.border = true; createTestRoom.x = 170; createTestRoom.y = 190; createTestRoom.width = 110; createTestRoom.height = 20; createTestRoom.text = "Create Test Room"; createTestRoom.addEventListener(MouseEvent.CLICK, createTestRoomClickListener); addChild(createTestRoom); // The remove-room button removeTestRoom = new TextField(); removeTestRoom.selectable = false; removeTestRoom.background = true; removeTestRoom.border = true; removeTestRoom.x = 170; removeTestRoom.y = 220; removeTestRoom.width = 110; removeTestRoom.height = 20; removeTestRoom.text = "Remove Test Room"; removeTestRoom.addEventListener(MouseEvent.CLICK, removeTestRoomClickListener); addChild(removeTestRoom); } } } |