overview
study the basic principles of multiuser application development
look at some of the code required to create a multiuser flash application
explore Unity, a multiuser application development kit
what is a multiuser application?
multiuser app: many users simultaneously experiencing the same environment
for example, a chat or a shared whiteboard (see simpledraw)
users connect to central server application
the server application manages:
application that connects to server is a "client application" (aka a "client")
multiuser application requirements
fast communication between client and server (high responsiveness)
a persistent connection between the client and the server
tcp/ip socket connections in flash
flash supports two systems for creating multiuser apps
XMLSocket
(transfer XML over tcp/ip)Unity is an XMLSocket server
both flashcom and xmlsocket clients connect to the server over persistent tcp/ip connections
XMLSocket-based applications
to create an XMLSocket
based application, we must:
1) create a server application that...
2) create a client application that...
XMLSocket
XMLSocket
instance (XMLSocket.connect()
)XMLSocket.send()
and XMLSocket.onData()
or XMLSocket.onXML()
XMLSocket client basic code
here's the basic code required to make an XMLSocket-based client
create an XMLSocket
instance
var xsock:XMLSocket = new XMLSocket();
define a method to handle incoming messages
xsock.onXML = function (xmlObj:XML):Void { trace("Some XML arrived:"); trace(xmlObj); };
define a method to handle connection information
xsock.onConnect = function (success:Boolean):Void { if (success) { // We're connected! trace("Connected to server."); // Now we can send a message to the server. // We're using Unity 2 in this test, so we'll send // an arbitrary message that Unity understands. this.send("<UPC><ROOMID>unity</ROOMID><METH>getNamespaceList</METH></UPC>"); } else { trace("Connection to server failed.") } };
attempt to connect our XMLSocket instance to the server
var connectSuccess:Boolean = xsock.connect("localhost", 9100); if (connectSuccess) { trace("Initial connection attempt succeeded. Waiting for response from server."); } else { trace("Initial connection attempt failed"); }
the need for a framework
challenge of creating multiuser apps is not using XMLSocket
challenge is managing communication and logic between potentially hundreds of clients
every multiuser app, whether business, art, or games, needs the same basic features:
rather than recreate those features from scratch for each project, it's better to use a framework, such as Unity
Unity overview
Unity is a generic framework for developing multiuser applications
can use it to make any kind of multiuser application (not just chat)
Unity Multiuser Development Kit has two parts:
Unity Multiuser Server
Java-based
handles client connection/disconnection
manages client communications
manages client groups
handles database connectivity
supports multiple client types (Java, C++, Flash, etc)
no audio/video support
UClient for Macromedia Flash
ActionScript 2.0 class library for application development
extensive collection of samples and templates
allows client-only development: Unity apps can be created entirely in flash. no server code required.
Unity core concepts
fundamental architecture: "groups of connected users that communicate by sharing data and invoking methods on each other"
clients
rooms
namespaces
room attributes
client attributes
remote method invocation
the server, illustrated
clients
users connected to the server
can be anonymous or registered (i.e., required to log in)
whether registered or not, every client gets a server-generated id
represented by two actionscript classes:
UClient
RemoteClient
UClient class
UClient
makes the initial connection to the server
handles all communication with the server
used to register and login clients
provides central access to room list and other clients on the server
used to set client attributes
used to invoke methods on other clients
RemoteClient class
RemoteClient
represents other users connected to the server
stores information about the user:
client attributes
client attributes are like variables for each client
when a client sets an attribute, other clients see the new value automatically
client attributes are managed by the server
client attributes can be saved permamently to a database
example uses:
client attribute code example
a client sets an attribute with setClientAttribute()
others respond to the change with onUpdateClientAttribute()
for example, here's the code to set the client attribute "username":
client.setClientAttribute("username", "dave", null, true, false, false, true);
parameters are: attribute name, attribute value, scope, attribute is shared, attribute is persistent, value is appended, attribute value is unique
code to respond to a change in the client attribute "username":
public function onUpdateClientAttribute (e:URoomEvent):Void { var attrName:String = e.getChangedAttr().attrName; var attrVal:String = e.getChangedAttr().attrVal; var oldVal:String = e.getChangedAttr().oldVal; var clientID:String = e.getClientID(); var status:String = e.getStatus(); // If the username changed display the new info on screen. if (attrName == "username") { handleUsernameUpdate(clientID, attrVal, status); } }
remote method invocation
use UClient
class to invoke methods on other clients
invoke methods on an individual user or groups of clients
four remote-invocation methods:
UClient.invokeOnClient()
UClient.invokeOnRoom()
UClient.invokeOnNamespace()
UClient.invokeOnAll()
remote method invocation example
this code invokes displayMessage()
on all clients in the room "chatapp.sportsChatRoom":
theUClient.invokeOnRoom("displayMessage", "chatapp.sportsChatRoom", true, "Hello world!");
"chatapp" is the namespace
third argument, true
, indicates that the method should also be invoked on the message sender
fourth argument, "Hello world!", is passed to displayMessage()
other clients in the room must implement displayMessage()
method
public function displayMessage (clientID:String, msg:String):Void { output.text += "User" + clientID + " says: " + msg + "\n"; }
rooms
room is a group of users
in actionscript, rooms are represented by the URoom
class
URoom
instances are created automatically when a room is added to the server
URoom
instances broadcast the following events:
creating rooms
rooms can be created in three ways:
RoomManagementServices
class (java)RoomManager
class (actionscript)getRoomManager().createRoomOnServer("sportsChatRoom", "chatapp", true, true, 50);
arguments: room name, containing namespace, dieOnEmpty, clientListNotification
when a room is created, the namespace containing it broadcasts an onAddRoom()
event
joining and leaving rooms
to join a room, use URoom.join()
theClient.getRoomManager().getRoom("chatapp.sportsChatRoom").join();
to leave a room, use URoom.leave()
theClient.getRoomManager().getRoom("chatapp.sportsChatRoom").leave();
room attributes
room attributes store information about the environment
for example:
this code sets a "highscore" attriubte
theRoom.setAttributeOnServer("highscore", "1000", true, true, false);
arguments are: attr name, attr val, isShared, isPersistent, appendVal
clients respond to a change in a room attribute using onUpdateRoomAttribute()
:
public function onUpdateClientAttribute (e:URoomEvent):Void { if (e.getChangedAttr().attrName == "highscore") { highscore_txt.text = e.getChangedAttr().attrVal; } }
namespaces
namespace is a group of rooms
create namespaces to hold rooms
in actionscript, namespaces are represented by the NameSpace
class
use RoomManager.createNamespaceOnServer()
to create namespaces
NameSpace
instances broadcast the following events:
an example: chat
let's look an example: a chat application
basic characteristics of a chat:
logic flow: creating and joining a room
here's the logic flow for creating and joining a room in a simple chat app
logic flow: setting a user name
here's the logic flow for setting a user name in a simple chat app
logic flow: sending a chat message
here's the logic flow for sending a message in a simple chat app
uClientCore architecture
here's the basic architecture for an application built with uClientCore:
example chat architecture
here's the basic architecture for a chat application:
questions?
any questions? email unity@moock.org