• Examples (iOS)
• Examples (Android)
• Examples (C++)
Server API Documentation

 

» Lobby

» Overview

In this tutorial you willl learn how to build a basic chat and lobby application in Unity using the C# API for SmartFoxServer 2X.

Exchanging chat messages is the most basic functionality provided by SmartFoxServer 2X: users connected to the same Zone can send public messages to all the other users in the same Room, private messages to specific users (regardless the Room they are in) and a different kind of private messages (called buddy messages) if the Buddy List system is enabled. Also, additional "super powers" are given to users being recognized as moderators or administrators.

The chat functionalities provided by SmartFoxServer 2X can be the core of a fully featured chat website/application, or a complementary system to allow users to exchange messages during game matches or in other kind of applications. In all cases SmartFoxServer provides additional features to build a complete chat system, like moderation controls, anti-flood filtering capabilities and an advanced words filter which supports regular expressions and white-list/black-list modes.

The example will show and explain the following functionalities:

The Unity scene uses a number of world-space canvases to display various panels dedicated to the different functionalities listed above.

It is recommended to have run through the Connector tutorial before looking at this example.

>> DOWNLOAD the source files <<

» Setup & run

In order to setup and run the example, follow these steps:

  1. make sure your SmartFoxServer 2X installation contains the BasicExamples Zone definition;
  2. start SmartFoxServer 2X (v2.13 or later is highly recommended);
  3. start Unity (v5.6 or later required);
  4. in the Projects panel click on the Open icon and browse to the /client/Lobby folder, then click the Open button;
  5. wait for the project setup completion (Unity needs to regenerate some libraries);
  6. go to the Project panel, click on the Assets folder and double click on the MainScene scene to open it;
  7. if SmartFoxServer and Unity are not running on the same machine, change the IP address of the server in the inspector as described later in this document;
  8. click on the Play button to run the example in the Unity Editor, or go to the Build settings panel and build it for your target platform of choice.

All relevant assets are contained in the Assets/LobbyAssets folder; in particular the C# code is in the Scripts subfolder and the SmartFoxServer 2X client API DLLs are in the Plugins subfolder. Read the introduction to understand why multiple DLLs are used.

» Code highlights

Code for this example is contained in the script file called Lobby in the Scripts subfolder, attached to the Controller game object in the scene.
The structure of the file is a basic Unity C# script with a Start() and Update() methods. Additionally there are a number of listeners for the event generated by the UI components (mostly buttons), some helper methods and the listeners for the SmartFoxServer client API events.

» Connection

The connection code is very similar to the code from the Connector example. The main difference is that socket policy prefetch (required in WebPlayer build) has been moved to the Start method and the connection settings are retrieved from the Lobby script component's inspector values set on the Controller game object. See the screenshot below.

Once the server connection has been made (OnConnection listener called with parameter "success" set to true), then the login is attempted.

» Login

To handle a login request through the various response events, we have to make sure to add an event handler for the LOGIN and LOGIN ERROR events. The LOGOUT event is also available, but it isn't used in this example.

sfs.AddEventListener(SFSEvent.LOGIN, OnLogin);
sfs.AddEventListener(SFSEvent.LOGIN_ERROR, OnLoginError);

In the UI, the user is asked for a Zone name and a username. In a "real world" setting this is most likely something you don't want to leave up to your users but rather decide for yourself in your code. Also, you would display a password input to give access to registered users only (this requires coding a server side Extension, as described in this recipe).
The Zone name corresponds to a Zone defined in the SFS2X server side configuration. You can define as many Zones as you want and each Zone is treated like an isolated world where your users can interact. In this example just leave it at the default value (fetched from the inspector as shown in the previous image) to connect to a Zone that's already defined in a default SFS2X installation.

The code to send the given information to the server for a login check is simple and follows the basic structure of sending any type of request to the server via the SmartFox.Send() method. Except for very special requests like making a connection, the client will send the requests in this way — be it build-in or Extension requests.

sfs.Send(new Sfs2X.Requests.LoginRequest(nameInput.text));

As the Zone name is not directly passed to the LoginRequest, the API uses the value set in the ConfigData object (created before attempting the connection).

When the response comes back for a successful login, the code rotates the camera to frame the actual lobby interface, prints some messages to the chat interface, populates the list of Rooms available in the Zone and joins the first one.

private void OnLogin(BaseEvent evt) {
    User user = (User) evt.Params["user"];

    // Rotate camera to main panel
    cameraAnimator.SetBool("loggedIn", true);

    // Set "Hello" text
    helloText.text = "Hello " + user.Name;

    // Clear chat panel, user list
    chatText.text = "";
    userListText.text = "";

    // Show system message
    string msg = "Connection established successfully\n";
    msg += "SFS2X API version: " + sfs.Version + "\n";
    msg += "Connection mode is: " + sfs.ConnectionMode + "\n";
    msg += "Logged in as " + user.Name;
    printSystemMessage(msg);

    // Populate Room list
    populateRoomList(sfs.RoomList);

    // Join first Room in Zone
    if (sfs.RoomList.Count > 0) {
        sfs.Send(new Sfs2X.Requests.JoinRoomRequest(sfs.RoomList[0].Name));
    }
}

NOTE
SmartFoxServer 2X requires a client to be fully logged in and joined to a Room to be able to interact with it. Otherwise all communication will be ignored and the client will be disconnected after a while.

» Rooms list

The client API has a RoomManager class representing the interface to work with Rooms. For the lobby we want to show a list of the Rooms in the current Zone. Those are displayed as buttons in a scrollable panel in the UI; the user can switch the Room he is in by clicking it.

The previous code snippet shows how to get the Rooms list from the SmartFox instance directly, using an helper property. An alternative way makes use of the RoomManager class mentioned before.

List<Room> roomList = sfs.RoomManager.GetRoomList();

In the populateRoomList() helper method, the list is processed creating the clickable UI items (this tutorial describes in great detail how this is done).

» Users list

The UI lists the users who are also in the same Room as the current client. The list is a simple text area where the name of each user is printed. In a more complex scenario, you could create another interactive list (like the list of Rooms), for example to start a private chat with one of the users.

The list of User objects is contained in the Room object; this property is available if the client has joined the Room (see the OnLogin() handler) successfully. In order to be aware of the status of the join process, we need two specific listeners to our SmartFox instance:

sfs.AddEventListener(SFSEvent.ROOM_JOIN, OnRoomJoin);
sfs.AddEventListener(SFSEvent.ROOM_JOIN_ERROR, OnRoomJoinError);

If an error occurs (for example all user slots in the Room are taken — or, in other words, the Room is full), an error message is printed in the chat interface by the OnRoomJoinError() method; otherwise the OnRoomJoin() handler gets the list of User objects using the Room.UserList property and passes it to the populateUserList() helper method. This cycles through all the User objects populating a List<string> with the names, which in turn is sorted alphabetically and printed in the dedicated text area of the UI.

private void populateUserList(List users) {
    // Get user names
    List userNames = new List();

    foreach (User user in users) {
		string name = user.Name;

		if (user == sfs.MySelf)
			name += " (you)";
			
		userNames.Add(name);
	}

    // Sort list
    userNames.Sort();

    // Display list
    userListText.text = "";
    userListText.text = String.Join("\n", userNames.ToArray());
}

Additionally, in case other users enter or leave the same Room after we joined it, two more methods are used to update the list: OnUserEnterRoom() and OnUserExitRoom(). They both must be added as event listeners to the SmartFox instance:

sfs.AddEventListener(SFSEvent.USER_ENTER_ROOM, OnUserEnterRoom);
sfs.AddEventListener(SFSEvent.USER_EXIT_ROOM, OnUserExitRoom);

» Sending and receiving chat messages

Now we can examine the heart of a chat/lobby application: how to send and receive public messages. We already have our input field ready for use and a "Send" button, all setup in the UI.

When the button is clicked (or the Enter key is pressed), a PublicMessageRequest instance is passed to the SmartFox.Send() method, with the content of the InputField.

sfs.Send (new Sfs2X.Requests.PublicMessageRequest(msgField.text));

Now let's see how we handle the reception of a public message. The event to look for is PUBLIC_MESSAGE which we earlier in the code registered a event handler for.

sfs.AddEventListener(SFSEvent.PUBLIC_MESSAGE, OnPublicMessage);

The event handler receives the standard BaseEvent event parameter containing the message string received ("message") and the sending User object ("sender"); we simply print the user name and the message to the chat text area.

private void OnPublicMessage(BaseEvent evt) {
    User sender = (User) evt.Params["sender"];
    string message = (string) evt.Params["message"];

    printUserMessage(sender, message);
}

To see more advanced uses of SmartFoxServer you can now move onwards to the next examples.

NOTE
You should also read the comments to methods and properties in the example source code for additional informations and possible code optimizations.

» More resources

You can learn more about the SmartFoxServer concepts discussed in this example by consulting the following resources: