Web browser based game. Unity3d + smartfoxserver

I am trying to make web browser based game (mmorpg).

I read this tutorial http://www.unifycommunity.com/wiki/index.php?title=Multiplayer_with_Unity_and_SmartFox_tutorial
And… it works when it’s stand alone application. It doesnt work when it’s web application.
I open login page, do what i have to do first level is opening ang it came back to login page sc_login.

	// We start working from here
	void Start() {
		Application.runInBackground = true; // Let the application be running whyle the window is not active.
		smartFoxClient = GetClient();
		if (smartFoxClient==null) {
			Debug.Log("smartFoxClient null");
			Application.LoadLevel("sc_login");
			return;
		}	
		SubscribeEvents();
		started = true;
		smartFoxClient.JoinRoom("Central Square");
	}

It looks like GetClient() doesn’t work. And my questions are:

  1. Can I do it in this way? I mean unity 3d + smartfox server in web browser?
  2. If i can what i do wrong?
  3. Any other ideas? other servers which are working with unity in web browser?
  4. Maybe some tutorials? :slight_smile:
  5. My english is realy terrible? I am from poland :wink:

You need to have policy validation either in smartfox or using the policy server that comes with Unity.
The webplayer needs to get validated before opening a socket to SmartFox.
You can find more info in the documentation about the webplayer security sandbox.

Yes, i did it before (i think so ^^ )

This code works.

using UnityEngine;
using System;
using SmartFoxClientAPI;
using System.Collections;
using System.Xml;
using System.IO;
 
public class ConnectionGUI : MonoBehaviour
{
	//----------------------------------------------------------
	// Setup variables
	//----------------------------------------------------------
	private string ip = "127.0.0.1";
	private int port = 9339;
	private string statusMessage = "";
	private int status = 2;

	//----------------------------------------------------------
	// Called when program starts
	//----------------------------------------------------------
	void Start()
	{
		TextAsset asset = (TextAsset) Resources.Load("database_cfg", typeof(TextAsset));
		if(asset != null)
		{
			XmlTextReader reader = new XmlTextReader(new StringReader(asset.text));
			while(reader.Read())
			{
				if(reader.Name == "hostname")
				{
					ip = reader.GetAttribute("label");
					//Debug.Log(reader.Name + " label = " + reader.GetAttribute("label"));
				}
				if(reader.Name == "port")
				{
					port = System.Int32.Parse(reader.GetAttribute("label"));
				}
				
			}
		}
		
		
		SmartFoxClient smartFox = new SmartFoxClient();
		SFSEvent.onConnection += HandleConnection;
		smartFox.Connect(ip, port);
	}
		
	//----------------------------------------------------------
	// Draw GUI every frame
	//----------------------------------------------------------
	void OnGUI()
	{


		GUI.Box(new Rect(0, 0, Screen.width, Screen.height), "");
		
			

		GUI.Label(new Rect(10, 10, 500, 100), " " + statusMessage);
		if(status == 0){
				
			
		}
		
		
	}

	//----------------------------------------------------------
	// Handle connection response from server
	//----------------------------------------------------------
	void HandleConnection(bool success, string error)
	{
		if (success)
		{
			statusMessage = "Polaczono z serwerem!";
			status = 1;
		}
		else
		{
			statusMessage = "Blad polaczenia z serwerem!";
			status = 0;
		}
	}	
}

If u said it shoud work in browser i have to try again from begining :wink:

i don’t see the connection to the policyserver at all in that script.

Ok it works in web browser but not very well

I used this code

using UnityEngine;

using System;
using System.Collections;         // for using hash tables
using System.Security.Permissions;  // for getting the socket policy
using SmartFoxClientAPI;            // to setup SmartFox connection
using SmartFoxClientAPI.Data;      // necessary to access the room resource

public class gui_Login : MonoBehaviour {
   
    // smartFox variables
    private SmartFoxClient smartFox;
    private string serverIP = "127.0.0.1";
    private int serverPort = 9339;        // default = 9339
    public string zone = "city";
    public bool debug = true;
   
    // variables used in script
    private string statusMessage = "";
    private string username = "";
   
    void Awake() {
        Application.runInBackground = true;     // Let the application be running while the window is not active.

        // Create SmartFox connection if not already available
        if ( SmartFox.IsInitialized() ) {
            Debug.Log("SmartFox is already initialized, reusing connection");
            smartFox = SmartFox.Connection;
        } else {
            if( Application.platform == RuntimePlatform.WindowsWebPlayer ) {
                // Only set this for the webplayer, it breaks pc standalone
                // See http://answers.unity3d.com/questions/25122/ for details
                Security.PrefetchSocketPolicy(serverIP, serverPort, 3000);
            }
            try {
                Debug.Log("Starting new SmartFoxClient");
                smartFox = new SmartFoxClient(debug);
                smartFox.runInQueueMode = true;
            } catch ( Exception e ) {
                Debug.Log(e.ToString());
            }
        }
   
        // Register callback delegates, before callling Connect()
        SFSEvent.onConnection += OnConnection;
        SFSEvent.onConnectionLost += OnConnectionLost;
        SFSEvent.onLogin += OnLogin;
        SFSEvent.onRoomListUpdate += OnRoomList;
        SFSEvent.onDebugMessage += OnDebugMessage;
        //SFSEvent.onJoinRoom += OnJoinRoom;        // We will not join a room in this level

        Debug.Log("Attempting to connect to SmartFoxServer");
        smartFox.Connect(serverIP, serverPort);  
    }
   
    void FixedUpdate() {
        smartFox.ProcessEventQueue();
    }

    void OnGUI() {
       
        // server IP in bottom left corner
        GUI.Label(new Rect(10, Screen.height-25, 200, 24), "Server: " + serverIP);
       
        // quit button in bottom right corner
        if ( Application.platform != RuntimePlatform.WindowsWebPlayer ) {         
            if ( GUI.Button(new Rect(Screen.width-150, Screen.height - 50, 100, 24), "Quit") ) {
                smartFox.Disconnect();
                UnregisterSFSSceneCallbacks();
                Application.Quit();
            }
        }

        // Show login fields if connected and reconnect button if disconnect
        if (smartFox.IsConnected()) {
            GUI.Label(new Rect(10, 116, 100, 100), "Username: ");
            username = GUI.TextField(new Rect(100, 116, 200, 20), username, 25);
            if ( GUI.Button(new Rect(100, 166, 100, 24), "Login")  || (Event.current.type == EventType.keyDown  Event.current.character == '\n')) {
                smartFox.Login(zone, username, "");
            }
        } else {
            if ( GUI.Button(new Rect(100, 166, 100, 24), "Reconnect")  || (Event.current.type == EventType.keyDown  Event.current.character == '\n')) {
            Application.LoadLevel("_sc_test");
            }
        }
       
        // Draw box for status messages, if one is given
        // Contains some logic to parse message of multiple lines if necessary
        if (statusMessage.Length > 0)
        {
            int boxLength = 61;       // define length of status box
            int messageLength = statusMessage.Length;   // get length of status message
            string originalMessage = statusMessage;  // copy message in to work string
            string formattedMessage = "";            // define output message string
            int i = 0;
            while (i + boxLength < messageLength)      // iterate and add newline until over length
            {
                formattedMessage = formattedMessage + originalMessage.Substring(i,boxLength) + "\n";
                i = i + boxLength;
            }
            // add last piece of original message
            formattedMessage = formattedMessage + originalMessage.Substring(i,  boxLength - (i + boxLength - messageLength));
            // draw status box with message
            GUI.Box (new Rect (Screen.width - 420,10,400,48), formattedMessage);
        }
       
    }

    private void UnregisterSFSSceneCallbacks() {
        // This should be called when switching scenes, so callbacks from the backend do not trigger code in this scene
        SFSEvent.onConnection -= OnConnection;
        SFSEvent.onConnectionLost -= OnConnectionLost;
        SFSEvent.onLogin -= OnLogin;
        SFSEvent.onRoomListUpdate -= OnRoomList;
        SFSEvent.onDebugMessage -= OnDebugMessage;
        //SFSEvent.onJoinRoom -= OnJoinRoom;
    }

    void OnConnection(bool success, string error) {
        if ( success ) {
            SmartFox.Connection = smartFox;
            statusMessage = "Connected to SmartFox Server";
            Debug.Log(statusMessage);
        } else {
            statusMessage = "Can't connect! " + error;
            Debug.Log(statusMessage);
        }
    }

    void OnConnectionLost() {
        statusMessage = "Connection lost / no connection to server";
    }

    public void OnDebugMessage(string message) {
        Debug.Log("[SFS DEBUG] " + message);
    }

    public void OnLogin(bool success, string name, string error) {
        if ( success ) {
            statusMessage = "Login for user \"" + name +  "\" successful.";
            // Lets wait for the room list
        } else {
            // Login failed - lets display the error message sent to us
            statusMessage = "Login error: " + error;
        }
    }

	/* 
    // We will not join a room in this level, the NetworkController in the next scene will take care of that
    void OnJoinRoom(Room room)
    {
        Debug.Log("Room " + room.GetName() + " joined successfully");
        smartFox.SendPublicMessage(smartFox.myUserName + " has joined");
        // We can now move on to the next level
        UnregisterSFSSceneCallbacks();
        Application.LoadLevel("sc_City");
    }

	*/

   
    void OnRoomList(Hashtable roomList) {
        try {
            foreach (int roomId in roomList.Keys)   {         
                Room room = (Room)roomList[roomId];
                if (room.IsPrivate()) {
                    Debug.Log("Room id: " + roomId + " has name: " + room.GetName() + "(private)");
                }
                Debug.Log("Room id: " + roomId + " has name: " + room.GetName());
            }
            // Users always have to be in a room, but we'll do that in the next level
            /*
            if (smartFox.GetActiveRoom() == null) {
                smartFox.JoinRoom("Central Square");
            }*/ 
            UnregisterSFSSceneCallbacks();
            Application.LoadLevel("_sc_test");
        }
        catch (Exception e) {
            Debug.Log("Room list error: "+e.Message+" "+e.StackTrace);
        }
    }
}

It works but i have to wait about 1-2 minutes to run it in browser… it is loading and then is a minute of waiting without any answer from firefox. It is becouse of browser or becouse of bad config in server?

I have smartfoxserver on the same computer with working policy server.

Anyone had that kind of problem?

it shouldn’t take that long, normaly you don’t even notice it.
you will have to debug and see what exactly happens in between.

It works i standallone PC, and in web browser. But in browser it is freezing fo about 25-30 seconds.

I checked, it works in LAN :slight_smile:

But still freezes on

Security.PrefetchSocketPolicy(serverIP, serverPort, 3000);

Without this part of code it of course cant connect.

hmm ok, this might be a problem :

smartFox.runInQueueMode = true;
void FixedUpdate() {
        smartFox.ProcessEventQueue();
}

try changing that to :

	void Start ()
	{
		if (SmartFoxConnection.IsInitialized) {
			sfClient = SmartFox.Connection;
		} else {
			if(Application.isWebPlayer || Application.isEditor)
			{
				if(Security.PrefetchSocketPolicy(ServerIp, ServerPort))
				{
					sfClient = new SmartFox (true);
					loginErrorMessage = "auth success...";
				} else {
					loginErrorMessage = "auth failed...";
					return;
				}
			} else {
				sfClient = new SmartFox (true);
			}
		}
		sfClient.AddEventListener (SFSEvent.CONNECTION, OnConnectionHandler);
		sfClient.AddEventListener (SFSEvent.LOGIN, OnLoginHandler);
		sfClient.AddEventListener (SFSEvent.LOGIN_ERROR, OnLoginErrorHandler);
		sfClient.AddEventListener (SFSEvent.LOGOUT, OnLogoutHandler);
		sfClient.AddEventListener (SFSEvent.CONNECTION_LOST, OnConnectionLostHandler);
		sfClient.AddEventListener (SFSEvent.CONNECTION_RETRY, OnConnectionRetry);
		sfClient.AddEventListener (SFSEvent.UDP_INIT, OnUdpInitHandler);
		sfClient.AddEventListener (SFSEvent.ROOM_JOIN, OnJoinRoomHandler);
		sfClient.AddLogListener (LogLevel.INFO, OnDebugMessage);
		sfClient.Connect (ServerIp, ServerPort);
		loginErrorMessage = "Connecting ...";
	}

	void FixedUpdate ()
	{
		sfClient.ProcessEvents ();
	}

Although i’m not sure, it might also work your way. Maybe try it out and see if it makes a difference.