RMI Elevator System: Server-Side Code Analysis

AscensorRMI: Server Package

This section details the AscensorRMI class, which extends UnicastRemoteObject and represents a remote elevator object.


package server;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import interfaz.GestorAscensores;

public class AscensorRMI extends UnicastRemoteObject {
    private static final long serialVersionUID = 1L;
    Gate door;
    private int floor;
    private int state;
    private int id;
    int model;

    public AscensorRMI(int num) throws RemoteException {
        door = new Gate();
        floor = 0;
        id = num;
        state = 0;
        System.out.println("Elevator " + num + " created");
    }

    public int getPiso() throws RemoteException {
        return floor;
    }

    public int getId() throws RemoteException {
        return id;
    }

    public int getEstado() throws RemoteException {
        return state;
    }

    public synchronized void go(int pisoDest) throws RemoteException {
        if (pisoDest > floor) {
            raise(pisoDest);
        } else {
            down(pisoDest);
        }
    }

    private void down(int pisoDest) {
        door.close();
        state = -1;
        while (floor > pisoDest) {
            System.out.println("Elevator " + id + " I'm on floor " + floor);
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            floor--;
        }
        System.out.println("Elevator " + id + " I have come to the floor " + floor);
        state = 0;
        door.open();
    }

    private void raise(int pisoDest) {
        door.close();
        state = 1;
        while (floor < pisoDest) {
            System.out.println("Elevator " + id + " I'm on floor " + floor);
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            floor++;
        }
        System.out.println("Elevator " + id + " I have come to the floor " + floor);
        state = 0;
        door.open();
    }
}

GestorAscensoresRMI: Managing Elevators

The GestorAscensoresRMI class manages multiple AscensorRMI instances. It implements the GestorAscensores interface.


package server;

import interfaz.GestorAscensores;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class GestorAscensoresRMI extends UnicastRemoteObject implements GestorAscensores {
    private static final long serialVersionUID = 1L;
    private AscensorRMI lifts[] = new AscensorRMI[5];

    public GestorAscensoresRMI() throws RemoteException {
        for (int i = 0; i < 5; i++) {
            lifts[i] = new AscensorRMI(i);
        }
    }

    public AscensorRMI[] getAscensores() {
        return lifts;
    }

    public int getEstado(int id) throws RemoteException {
        return lifts[id].getEstado();
    }

    public int getId(int id) throws RemoteException {
        return lifts[id].getId();
    }

    public int getPiso(int id) throws RemoteException {
        return lifts[id].getPiso();
    }

    public void go(int pisoDest, int id) throws RemoteException {
        lifts[id].go(pisoDest);
    }
}

Server: RMI Server Implementation

This section describes the Server class, responsible for binding the GestorAscensoresRMI object to the RMI registry.


package server;

import java.rmi.*;
import java.util.Scanner;

public class Server {
    GestorAscensoresRMI manager;

    public Server() throws Exception {
        manager = new GestorAscensoresRMI();
        Naming.rebind("rmi://localhost/Manager", manager);
    }

    public void check() throws Exception {
        int option;
        do {
            option = menu();
            switch (option) {
                case 1:
                    enseñarAscensores();
                    break;
                case 2:
                    break;
                default:
                    System.out.println("Invalid option");
            }
        } while (option != 2);
        System.out.println("You left the system");
    }

    private void enseñarAscensores() {
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println("Elevator - " + manager.getAscensores()[i].getId() +
                        " is in The " + " floor: " + manager.getAscensores()[i].getPiso() +
                        " state: " + manager.getAscensores()[i].getEstado());
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public int menu() {
        Scanner keyboard = new Scanner(System.in);
        int option;
        System.out.println("1 .- See elevators");
        System.out.println("2 .- Exit");
        System.out.println();
        System.out.print("Choose option:");
        option = keyboard.nextInt();
        return option;
    }

    public static void main(String[] args) {
        try {
            java.rmi.registry.LocateRegistry.createRegistry(1099);
            Server manager = new Server();
            manager.check();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Door: Gate Class

The Gate class represents the elevator door and its state (open or closed).


package server;

import java.io.*;

public class Gate implements Serializable {
    private static final long serialVersionUID = 1L;
    boolean state;

    public Gate() {
        state = true;
    }

    public void open() {
        if (!state) {
            System.out.println("\tAbriendo door");
            // code to cause failure of a second
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            state = true;
        }
    }

    public void close() {
        if (state) {
            System.out.println("\tCerrando door");
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            state = false;
        }
    }
}