Simple Chat Tutorial

From EsWiki

Jump to: navigation, search

This is a tutorial that covers the steps in making a simple chat system.

Contents

What You'll Learn

  • Setting up a basic user interface to print and send messages
  • How to send public messages to the server
  • How to receive public message from the server
  • How to receive user list changes and display it for the user

Prerequisites

Download

If you wish to simply download the entire set of Simple Chat files (source code and compiled), it is found in SimpleChatTutorial.zip. Replace the com folder with the AS3 API files found in your own version of ES4, then recompile.

Let's Get Started!

In the steps below you will learn how to set up a basic user interface, send public messages to the server and receive public messages from the server.


Create a new FLA file

Create a new FLA file (AS3) and save it. Make sure the ES4 API is in the classpath. We recommend that you add the AS2 and AS3 APIs to the global classpath so that you don't have add it for every application.

Layers

First we will make 3 layers, to separate things out about it make it simpler to read. Name the layers Labels, Actions, and Assets. Right click on Assets and select Guide. This will make it not show up in the actual movie, but just used while in the editor.

Load ServerSettings.xml

Now we will add some code to frame 1, in the Actions layer that will load an XML file that has the server details.

  stop();
  ///////////////////////////////
  //Load the ServerSettings.xml
  ///////////////////////////////
  /*
     serverInfo will end up containing the listener information from the ServerSettings.xml file
     It will look something like this:
        serverInfo (object)
           text (object)
              ip(string)
              port(number)
           rtmp (object)
              ip(string)
              port(number)
  */
   
  import flash.events.Event;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  
  var serverInfo:Object;
  var loader:URLLoader = new URLLoader();
  loader.addEventListener(Event.COMPLETE, serverSettingsComplete);
  
  function serverSettingsComplete(e:Event) {
    var loader:URLLoader = URLLoader(e.target);
    var result:XML = new XML(loader.data);
    serverInfo = new Object();
    for each (var lis:XML in result.Listener) {
       var protocol:String = lis.@protocol;
       var ip:String = lis.@ip;
       var port:Number = Number(lis.@port);
       serverInfo[protocol] = new Object();
       serverInfo[protocol].ip = ip;
       serverInfo[protocol].port = port;
    }
    gotoAndStop("Main");
  }
   
  var request:URLRequest = new URLRequest("ServerSettings.xml");
  loader.load(request);

This code will first stop the movie at this frame, and then load and xml file called ServerSettings.xml . Once the results have been received, it puts the values in the serverInfo object and will go to the frame labeled Main.

ServerSettings.xml

The XML file will look like this:

 <Listeners>
     <Listener ip="127.0.0.1" port="9898" protocol="text" />
     <Listener ip="127.0.0.1" port="1935" protocol="rtmp" />
 </Listeners>

These are the default values which can be changed to what you want. Save this as ServerSettings.xml in the same folder as the .fla .

Basic UI

Example Layout
Example Layout

Next we will look at the layout for the UI. Insert a new frame on frame 10 and frame 30 for all layers. In the Labels layer at frame 10, label the frame Main.

Next go to Insert -> New Symbol. Create a movieclip called Interface. This is where we will store the user interface.

Now we must figure out what kind of UI elements we will need. The elements we will want are:

  • Chat window to display previous messages
  • Textbox to enter new messages
  • Send button to send new messages
  • List of users in the room

Note: It may be a good idea to place a rectangle in the Interface movieclip the size of the stage, so you can easily tell where to place UI elements.

You will want the Components window open.

For the Chat window, we will use a Text Area Component. Make the size you want it and label it c_chatBox. (Note: the use of the c in front signifies it is a component)

Next create a List Component for displaying the user list. Label it c_userList and place where desired.

Create a TextInput Component and label it c_textInput.

Finally, create a Button Component and label it c_sendButton.

Congratulations, you have successfully set up the UI!

Next we will look at the code that will use the UI you have set up.

Creating The Main class

Base Setup

We are going to create a class that manages the UI and both sending and receiving messages. This class will actually be the same class as the Interface movieclip we just made.

Find the Interface movieclip in the library (Windows -> Library ). Right-click on it and select Properties. Click on Advanced and then enable Export for Actionscript. Change the Class name from Interface to Main.

Now we are going to create the Main class. Create a new Actionscript file called Main.as in the same folder. Have Main extend Movieclip, so it will read: public class Main extends MovieClip.

We are going to need quite a few imports, so place these in the files.

  	//Flash imports
  	import com.electrotank.electroserver4.message.request.PublicMessageRequest;
  	import fl.controls.List;
  	import fl.controls.TextArea;
  	import flash.display.MovieClip;
  	import flash.events.Event;
  	import flash.text.TextField;
  	import flash.display.SimpleButton;
  	import flash.events.MouseEvent;
  	//ElectroServer imports
  	import com.electrotank.electroserver4.message.event.JoinRoomEvent;
  	import com.electrotank.electroserver4.message.event.PublicMessageEvent;
  	import com.electrotank.electroserver4.user.User;
  	import com.electrotank.electroserver4.message.event.ConnectionEvent;
  	import com.electrotank.electroserver4.message.request.LoginRequest;
  	import com.electrotank.electroserver4.message.response.LoginResponse;
  	import com.electrotank.electroserver4.ElectroServer;
  	import com.electrotank.electroserver4.message.MessageType;
  	import com.electrotank.electroserver4.message.event.UserListUpdateEvent;
  	import com.electrotank.electroserver4.message.request.CreateRoomRequest;
  	import com.electrotank.electroserver4.room.Room;


Now that the class is setup, lets go into the code.

Variables and Initialization

A few variables will be used through the class, these are:

  	private var es:ElectroServer;
  	private var serverInfo:Object;
  	private var myRoom:Room;

They will be used to store data once it is available.

The first function we will look at is the initialize function, which will connect to the server using the serverObject and set up the listeners for handling data.

  	public function initialize(serverInfo:Object):void 
  	{
  		
  		this.serverInfo = serverInfo;
  		//Create the ElectroServer instance
  		es = new ElectroServer();
  		//Establish listeners
  		es.addEventListener(MessageType.ConnectionEvent, "onConnectionEvent", this);
  		es.addEventListener(MessageType.LoginResponse, "onLoginResponse", this);
  		es.addEventListener(MessageType.JoinRoomEvent, "onJoinRoomEvent", this);
  		es.addEventListener(MessageType.PublicMessageEvent, "onPublicMessageEvent", this);
  		es.addEventListener(MessageType.UserListUpdateEvent, "onUserListUpdateEvent", this);
  		//Create the connection
  		output("Attempting connection with this ip/port combo: "+serverInfo.text.ip+":"+serverInfo.text.port);
  		es.createConnection(serverInfo.text.ip, serverInfo.text.port);
  		
  		
  		c_sendButton.addEventListener(MouseEvent.CLICK, onButtonClick);
  	}			

As you see this function mainly just sets up all of the listeners and connects to the server. When you add an event listener on the es object, when it receives an event of the given type (say ConnectionEvent), it will call the given function name of the given object (this, and onConnectionEvent in this case).

This is done for all the needed message types to correctly handle the data. The other event you see if for when the send button is clicked.

We will now look at the functions that handle the events.


Connecting and Logging In

The first function we will look at is the onConnectionEvent function. This function is called when the client receives information back about their attempt to login to the server. It first checks to see if it was accepted, if so, it will attempt to login with a random user name. If it failed, it will output the error.

  	public function onConnectionEvent(e:ConnectionEvent):void 
  	{
  		if (e.getAccepted()) {
  			output("Connection accepted");
  			var name:String = "user"+Math.round(10000*Math.random());
  			output("Attempting to login as: "+name);
  			//Build the LoginRequest and populate it
  			var lr:LoginRequest = new LoginRequest();
  			lr.setUserName(name);
  			//send it
  			es.send(lr);
  		} else {
  			output("Connection failed: "+e.getEsError().getDescription());
  		}
  	}

The output function seen in this function and in the initialize function is as follows:

  	private function output(msg:String):void 
  	{
  		c_chatBox.appendText(msg+"\n");
  		c_chatBox.verticalScrollPosition = c_chatBox.maxVerticalScrollPosition;
  	}			

It simply adds the message to the chat box and scrolls it down as far as possible.

Next we will look at the onLoginResponseFunction. This function is similar to the onConnectionReponse function, as it also check to see if it successful (as will many response functions). If it is, it will attempt to join a room, if not, it will display an error message.

  	public function onLoginResponse(e:LoginResponse):void 
  	{
  		if (e.getAccepted()) {
  			output("Login accepted.");
  			output("You are logged in as: "+e.getUserName());
  			joinRoom();
  		} else {
  			output("Login failed: "+e.getEsError().getDescription());
  		}
  	}			

Next we will look at joining the room.

Joining a Room

After the player has been successfully logged in, we will attempt to have the player join a room.

  	private function joinRoom():void {
  		//tries to create a room. if it already exists, then you join that room
  		//create the request
  		var crr:CreateRoomRequest = new CreateRoomRequest();
  		crr.setRoomName("MyRoom");
  		crr.setZoneName("ZoneName");
  		//send it
  		es.send(crr);
  	}			

The joinRoom function sets up a CreateRoomRequest object with the room name and zone name, then sends it to the server. Note: When a user creates a room, if successful, they automatically join the room.


The JoinRoomEvent is sent when a player actually joins a room, so if this is received, there has not been an error joining the room. We added the listener for the JoinRoomEvent in the initialize function.

  	public function onJoinRoomEvent(e:JoinRoomEvent):void 
  	{
  		myRoom = e.room;
  		showUserList();
  	}

The myRoom variable is set to the room we joined, and then user list is displayed with the initial users.

Next we will look at updating the user list.

Displaying the User List

The function onUserListUpdateEvent is called when ever a user join or exits the room (since we set up the listener earlier on). This function will just call showUserList, which displays the new list for the user.

  	public function onUserListUpdateEvent(e:UserListUpdateEvent) 
  	{
  		showUserList();
  	}			

The showUserList function gets the array of users in the room and removes all the entries in the c_userList component. It then adds all of the users to the c_userList component as separate entries.

  	private function showUserList():void 
  	{
  		var users:Array = myRoom.getUsers();
  		c_userList.removeAll();
  		for (var i:int=0;i<users.length;++i) {
  			var u:User = users[i];
  			c_userList.addItem({label:u.getUserName(), data:u});
  		}
  	}

Finally, we will look at sending and receiving messages.

Sending and Receiving Messages

A message is not sent until the send button is pressed. The onButtonClick function makes sure the correct thing was pressed, then attempts to send a message.

  	private function onButtonClick(e:MouseEvent):void 
  	{
  		if (e.target == c_sendButton) 
  		{
  			attemptSendMessage();
  		}
  	}

The attemptSendMessage function will make sure the message is not empty and then send the message. A new PublicMessageRequest is created, and the message, room, and zone are set. Then the request is sent to the server using the send function.

  	private function attemptSendMessage():void 
  	{
  		var msg:String = c_textInput.text;
  		if (msg != "") {
  			c_textInput.text = "";
  			//create the request
  			var pmr:PublicMessageRequest =new PublicMessageRequest();
  			pmr.setRoomId(myRoom.getRoomId());
  			pmr.setZoneId(myRoom.getZone().getZoneId());
  			pmr.setMessage(msg);
  			//send it
  			es.send(pmr);
  		}
  	}			

Finally, the client must listen for incoming messages and display them.

  	public function onPublicMessageEvent(e:PublicMessageEvent):void 
  	{
  		var from:String = e.getUserName();
  		var msg:String = e.getMessage();
     	
  		output(from+": "+msg);
  		
  	}			

The received message is retrieved from the PublicMessageEvent, along with the username and then outputted on screen.

Create an instance of Main

Lastly, we need to create an instance of Main. In frame 10 of Actions layer, add the following code:

      var main:Main = new Main();
      main.initialize(serverInfo);
      addChild(main)

Congratulations the tutorial is complete.

Finished!

See it's not that hard! You have just created a chat system, congratulations! From here you should continue with either the Hello World Plugin Tutorial or the Advanced Chat Tutorial.

Personal tools
download