How Fi Works: The Server

This is going to be real quick and straight forward. I’m not going to go into detail on the backend of the server in this post, that’s for in the next one, if you think you can handle it.

Lets go through what the server does when it starts up, shall we?

public class Main {

    public static String ServerIP = "";
    public static String _ip;
    public static int _portIn = 7774;
    public static int _portOut = 0;
    // IsModuleRunning
    public static List PausedModules = new ArrayList<>();
    public static boolean MasterSwitchIsRunning = true;

    ///
    /// Methods that get called from scripts/modules
    ///

    public static void main(String[] args) {

        Main app = new Main();

        // app is now the gateway.entry_point
        GatewayServer server = new GatewayServer(app);
        server.start();

        InitializeApp();
    }

    public static void InitializeApp() {

        try {
            Enumeration n = NetworkInterface.getNetworkInterfaces();
            for (; n.hasMoreElements(); ) {
                NetworkInterface e = n.nextElement();

                Enumeration a = e.getInetAddresses();
                for (; a.hasMoreElements(); ) {
                    InetAddress addr = a.nextElement();

                    if (!addr.getHostAddress().startsWith("192.")) continue;

                    Main.ServerIP = addr.getHostAddress();

                    System.out.println("IP of this system is  " + Main.ServerIP);
                }
            }
        } catch (SocketException e1) {
            e1.printStackTrace();
        }

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                try {
                    if (FiServerBackend.client.isConnected()) {
                        FiServerBackend.client.close();
                        System.out.println("The server is shut down!");
                    }
                } catch (IOException e) { /* failed */ }
            }
        });

        Runnable r = new Runnable() {
            public void run() {
                FiServerBackend.StartListeningToSocket();
            }
        };
        new Thread(r).start();

        FiServerBackend.RunPythonBackend();

        while (true) {
            FiServerBackend.SendMessageToSocket(new FiMessage(Console.askForInput("Send to phone:"), "FiCommand"));
        }
    }

    public static boolean IsModuleRunning(String moduleName) {
        if (!MasterSwitchIsRunning) return false;
        if (PausedModules.size() <= 0) return true;
        return !PausedModules.contains(moduleName);
    }

    // ModuleUpdated
    public void ModuleUpdated(String moduleName, String moduleTitle, String moduleDescription, int progress) {
        HashMap extras = new HashMap();
        extras.put("type", "Module");
        FiMessage msg = new FiMessage(
                new FiModuleUpdate(moduleName, moduleTitle, moduleDescription, Misc.Clamp(progress, 0, 100).intValue()),
                "FiUpdate",
                extras
        );
        if (FiServerBackend.client != null && FiServerBackend.client.isConnected())
            FiServerBackend.SendMessageToSocket(msg);
    }
}

main()

Let’s start with ‘main’, main is the first function that gets called when the server starts up. GatewayServer is what lets us communicate with the scripts, or modules. I’m not going to go into too much detail, so for now we’ll have to skip this part. Lets head on to InitializeApp()!

InitializeApp()

The first try-catch clause looks a bit complicated, but all it really does is get the IP address of the current machine.

Runtime.getRuntime().addShutdownHook

This piece of code gets called when the server is exited, this lets us clean up any open sockets or unfinished tasks.

Runnable r = new Runnable() {
            public void run() {
                FiServerBackend.StartListeningToSocket();
            }
        };
        new Thread(r).start();

All we care about here is this line of code:

FiServerBackend.StartListeningToSocket();

What this does is infinitely listen to incoming requests from wither a seed or an app. The surrounding code makes this line of code run in a separate thread, this means the execution of the code will continue while this line of code is working in the background.

FiServerBackend.RunPythonBackend();

This starts the Python modules.

while (true) {
            FiServerBackend.SendMessageToSocket(new FiMessage(Console.askForInput("Send to phone:"), "FiCommand"));
        }

And this asks the user for input, more specifically a command to send to the app.

while (true)

This is pretty much an infinite loop, don’t do this at home!

The rest

Every function from here on down is dedicated to the modules, for example, if a module wants to know if the user has paused it, all it has to do is call IsModuleRunning() and Fi will answer. If the module wants to show something to the user, for example a status update, it can call ModuleUpdated(), and so on.

Thank you for bearing through my messy code, I’ll be going into detail on the backend of Fi in the next blog post, ’till then!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s