javaNoob49854
javaNoob49854

Reputation: 43

What's the simplest way to make a local remote for a java program?

I'm trying to make a client remote for a java program, I've read about sockets but there seems to have several protocols and ways of doing that.

Basically I'd just want to be able to push button on the client part of the application and activate related functions on the server part, in local.

I guess I should be listening to a socket in a separate thread and transfer/read strings to know what was pushed? it's mostly for learning purpose.

I'd like some advice/quick explanation to know how to achieve this, I've seen examples of basic client sever communication but I didn't find anything really clear on how this should be done (new thread or not?) and clearly I seem to not fully understand the concept of inputstream/outputstream.

Upvotes: 2

Views: 2533

Answers (2)

toKrause
toKrause

Reputation: 512

A very simple way to let two Java applications (a server and a client) talk to each other, especially on the same machine, is to use Remote Method Invocation (RMI). RMI allows to share Objects between Java applications which means, it is a very high level abstraction of communication and removes the necessity to write custom network code or handle the involved concurrency.

Here is a very basic example:

Step 1: Create a common Interface

Create a common interface that describes the functionality provided by th server:

package com.example.remote;

import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RemoteControlInterface extends Remote, Serializable {

    public void sendCommand(String command) throws RemoteException;

}

This interface must extend java.rmi.Remote and java.io.Serializable and every methot must be able to throw a java.rmi.RemoteException. Put this in a library and use this library in the server and the client as well. How this is accomplished, depends on the IDE you're using. The simplest way is probably to put server, client and the common library in the same project.

Step 2: Create the server application

Create an implementation of the common interface in the server application:

package com.example.remote.server;

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

import com.example.remote.RemoteControlInterface;

public class RemoteControl extends UnicastRemoteObject implements RemoteControlInterface {

    private static final long serialVersionUID = 1L;

    protected RemoteControl() throws RemoteException {
    }

    @Override
    public void sendCommand(String command) throws RemoteException {
        System.out.println("remote control asked for " + command);
    }

}

The implementation of the common interface must extend java.rmi.server.UnicastRemoteObject.

Create the actual server application which publishes an instance of the implementation of RemoteControlInterface as remoteControl as a server that is listening on port 1234.

package com.example.remote.server;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Server {

    public static void main(String[] args) throws MalformedURLException, RemoteException, AlreadyBoundException {
        Registry registry = LocateRegistry.createRegistry(1234);
        registry.bind("remoteControl", new RemoteControl());
    }

}

Step 3: Create the client application

Create the actual client application which connects to a server on port 1234 and retrieves a published instance of RemoteControlInterface using the name remoteControl.

package com.example.remote.client;

import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import com.example.remote.RemoteControlInterface;

public class Client {

    public static void main(String[] args) throws AccessException, RemoteException, NotBoundException {
        Registry registry = LocateRegistry.getRegistry(1234);
        RemoteControlInterface greetingService = (RemoteControlInterface) registry.lookup("remoteControl");
        greetingService.sendCommand("helloWorld");
    }

}

This will cause the server application to print remote control asked for helloWorld on its console.

The parameters and the return value of all methods in the common interface may be:

  • Any primitive Java type (boolean, int, ...)
  • Any class the both applications share (String, Date, ...) that implements java.io.Serializable as long as both applications have the same version of the corresponding class file. The letter is true for all classes that are provided by the JRE and all classes placed in the common library.

While RMI can do much more, this should be sufficient to implement a simple remote control.

Upvotes: 2

Mark Stroeven
Mark Stroeven

Reputation: 696

Well,

by actually implementing a client side program and a server side program :)

in order to understand this you'll need some info about the basics of server side programming. Lets take a basic web / application server. Apache tomcat. You will make your fronted (the gui etc..) like you want it, lets say you make a button that says "click me, and I will say hello!"

when we click in that button you would need to launch a function (if it is a web app this will be in Javascript) that will send a message or "request" to the server. The server receives this request, processes it and sends a "response" containing data.

within a java web project you map certain URL's such as www.example.com/hello to certain classes containing code (servlets, or endpoints). normally you would also attach pieces of data to your "request" for the server to do something with.

Lets take a registration form as example. you would make several input field and when we click on submit the data from those fields is attached to the request and sent to the server. on the server side we would receive a request object (for example javax.servlet.httpservletrequest). from this object we can open an datastream and read the data attached to it.

normally (without the help from frameworks or JSON libraries) one would do:

 InputStream inputStream = request.getInputStream();
        if (inputStream != null) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                stringBuilder.append(charBuffer, 0, bytesRead);
            }

once you get the data, do something with it, and then send a response via the httpresponse object. that's the basic of server side computing. There is a lot more to this, for example sending asynchronous requests to the server. Using object notations to ease the reading from requests, using REST to easily access data from the we.

but to start try beginning with a simple tomcat project, and look at servlets, servlet mappings ec.

Upvotes: 0

Related Questions