21
$\begingroup$

How might I implement a local HTTP server using either Java, C#, C or purely Mathematica?

It should be able to respond with Mathematica input to GET and POST requests ideally on W7.

This is related although doesn't really work. If you would like you can read the license here

$\endgroup$
2
  • 2
    $\begingroup$ A small-scale web server implemented using ProcessLink and Go can be found here. $\endgroup$
    – WReach
    Apr 3, 2016 at 5:34
  • $\begingroup$ @WReach thank you I'm trying to get it to run on Windows despite appearing to be written for OSX. $\endgroup$
    – William
    Apr 3, 2016 at 18:36

5 Answers 5

28
$\begingroup$

The following guide shows how to conduct communication between nanohttpd, an http server for Java, and Mathematica. The result is a server that, if you go to its address in a web browser, displays the result of SessionTime[], i.e. the time since the Mathematica kernel associated to the server started.

I'm going to write as if the reader was using OS X with Maven installed because that is the operating system I am using, but this solution works on all operating systems with the proper, obvious, modifications. Directories and so on. On OS X Maven can be installed with Brew using

brew -install maven

Getting up and running with nanohttpd:

  1. Download the latest version of nanohttpd from Github.

  2. Follow the steps listed under "quickstart" on nanohttpd.org

Add this to the top of the sample app among the other imports:

import com.wolfram.jlink.*;

Locate JLink.jar on your harddrive. On OS X it is located at

/Applications/Mathematica.app/SystemFiles/Links/JLink

Navigate to the app's directory and run the following command to include JLink.jar in the Maven project (with the appropriate modifications):

mvn install:install-file -Dfile=/Applications/Mathematica.app/Contents/SystemFiles/Links/JLink/JLink.jar -DgroupId=com.wolfram.jlink -DartifactId=JLink -Dversion=1.0 -Dpackaging=jar

And modify the app's pom.xml by adding the file as a dependency:

  <dependency>
      <groupId>com.wolfram.jlink</groupId>
      <artifactId>JLink</artifactId>
      <version>1.0</version>
  </dependency>

Check that you can still compile the application and that it still works. Now if that's true, replace the code in App.java with this (see the sample program here):

import java.io.IOException;
import java.util.Map;
import com.wolfram.jlink.*;

import fi.iki.elonen.NanoHTTPD;

public class App extends NanoHTTPD {

    KernelLink ml;

    public App() throws IOException {
        super(8888);
        start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);

        try {
            String jLinkDir = "/Applications/Mathematica.app/SystemFiles/Links/JLink";
            System.setProperty("com.wolfram.jlink.libdir", jLinkDir); // http://forums.wolfram.com/mathgroup/archive/2008/Aug/msg00664.html

            ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname '\"/Applications/Mathematica.app/Contents/MacOS/MathKernel\" -mathlink'");

            // Get rid of the initial InputNamePacket the kernel will send
            // when it is launched.
            ml.discardAnswer();
        } catch (MathLinkException e) {
            throw new IOException("Fatal error opening link: " + e.getMessage());
        }

        System.out.println("\nRunning! Point your browers to http://localhost:8888/ \n");
    }

    public static void main(String[] args) {
        try {
            new App();
        } catch (IOException ioe) {
            System.err.println("Couldn't start server:\n" + ioe);
        }
    }

    @Override
    public Response serve(IHTTPSession session) {

        String msg = "<html><body><p>";

        try {
            ml.evaluate("SessionTime[]");
            ml.waitForAnswer();

            double result = ml.getDouble();

            msg = msg + Double.toString(result);
        } catch (MathLinkException e) {
            msg = msg + "MathLinkException occurred: " + e.getMessage();
        }
        msg = msg + "</p></body></html>";

        return newFixedLengthResponse(msg);
    }
} 

Look up the line with String jLinkDir = and confirm that the directory is right. If you are using another operating system than OS X you also have to configure the line with MathLinkFactory in it. Information about that is available here.

Compile the code and run it by (as you did before to run the sample app), navigating to the project's directory and executing the following commands:

mvcompile
mvn exec:java -Dexec.mainClass="com.stackexchange.mathematica.App"

where you have edited mainClass appropriately. You now have an HTTP server on the address http://localhost:8888/ that calls on a Mathematica kernel and uses its response to answer requests.

$\endgroup$
7
  • $\begingroup$ +1 Thank you for the response but being on Windows it is unlikely that I will accept this answer and give it the bounty. $\endgroup$
    – William
    Apr 5, 2016 at 2:39
  • $\begingroup$ @William It works on Windows but directories need to be changed. I don't have Windows so I can't try it, but if you try it on Windows then you can add a note detailing things that are specific to Windows. That would help people who come across this in the future. $\endgroup$
    – C. E.
    Apr 5, 2016 at 19:58
  • $\begingroup$ The following link for nanohttpd github.com/NanoHttpd/nanohttpd/wiki/5-minute-Tutorial states the following You'll need Linux or Mac OS..... $\endgroup$
    – William
    Apr 5, 2016 at 23:58
  • $\begingroup$ @William Java works on Windows, and Maven works on Windows. I don't see why NanoHTTPD shouldn't work on Windows. The guide you quote is written for Unix, that's all I think. $\endgroup$
    – C. E.
    Apr 6, 2016 at 0:31
  • 1
    $\begingroup$ @William The above code is written with JLink? $\endgroup$
    – C. E.
    Apr 6, 2016 at 2:04
14
$\begingroup$

The following is a sample implementation of a simple HTTP server in Wolfram Language code only:

https://github.com/arnoudbuzing/wolfram-server

You send it a POST request where the body data of the HTTP request contains the Wolfram Language code you wish to evaluate.

The (running) wolframserver.wls script processes the request by evaluating the code string and returning the result as ExpressionJSON which should be generic enough to parse and process in most programming languages (including javascript for web browsers).

It's a new and evolving project for me, so please give it a star if this is useful to you because that will tell me how much interest there is in this (and how much time to spend on it for making improvements).

$\endgroup$
9
$\begingroup$

Starting in Mathematica 12, there is a built-in function SocketListen that can start a web server and respond to HTTP requests.

SocketListen is also available in Mathematica 11.2, but only on an experimental basis.

Further reading: Network Programming Guide.

$\endgroup$
4
$\begingroup$

In 2023 new players joined our game

  • TCPServer - a general purpose tcp-server written using only WL
  • HTTPServer - an extension to TCPServer to manage GET/POST requests
  • WebSocketServer - an extension to use Websockets protocol
  • CSockets - a custom written in C high-performance asynchronous cross-platform sockets interface (as a replacement of buggy native SocketListener. Synthetic test shows x67 of performance gain Server->Client)
$\endgroup$
4
  • 1
    $\begingroup$ Can the ``HTTPServer` use the CSockets to serve the GET/POST routes in place of the buggy SocketListener that has not seen any development for several years? It will be nice if you add a dockerfile support to build this server and serve those REST end points. Looking forward to further development and docs to use it as mma based tiny prototyping back-ends. $\endgroup$ Aug 16 at 17:49
  • $\begingroup$ Thanks, @PlatoManiac! I will ask a maintainer of those packages to reply ;) $\endgroup$ Aug 16 at 18:14
  • $\begingroup$ @PlatoManiac of course! This is the main purpose of creating this package. A faster and more reliable interface for exchanging TCP packets. Now this package and other packages related to it are in the process of finalization, but you can write to me on the mail, which is specified on the github or contact me in any other way. $\endgroup$ Aug 16 at 19:28
  • $\begingroup$ @PlatoManiac And yes docker file in todo list. $\endgroup$ Aug 16 at 19:29
3
$\begingroup$

Yes (and using pure Mathematica or WolframEngine)

https://jerryi.github.io/tinyweb-mathematica/

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.