Tink http and tink web with pure haxe tcp server

I spent some time trying to get tink_web working so I could implement a simple web server with a web api, like REST.

My problem is I don’t want it to run on top of a nodejs or php container, I want a pure haxe solution running on sys targets.

Is there an implementation of a tcp container and an example of it working?

I know there’s a Tcp container class, but it seems to need to forward the work off to an actual implementation of a tcp server or something?

I actually switched over to using snake-server which is a pure haxe web server ported from Python and seems to be focused on serving static content.

I’m wondering if I’m missing something with tink web and maybe it’s easier than I think to get it working as a standalone server on sys targets?

If not is it possible to integrate snake-server as a container for tink-http?

I like tink’s routing, it would be nice to use it instead of having to re-write it from scratch.

ANY comments appreciated, or maybe a person I can direct this question to, would be helpful.

Thanks in advance!

Clay

I don’t know much but I will say I’m currently launching a Hashlink binary via NodeJS in a Docker container. Presumably you could use Hashlink as your server with the right setup.

1 Like

There is a base SSL socket server example as a starting point Prototype SSL Socket Server - Other - Haxe programming language cookbook

1 Like

I believe tink_tcp worked on sys targets (to some extent) last time I checked

1 Like

I don’t know much but I will say I’m currently launching a Hashlink binary via NodeJS in a Docker container. Presumably you could use Hashlink as your server with the right setup.

Thanks for the reply. I will be looking into using Hashlink as the sys target eventually.

There is a base SSL socket server example as a starting point Prototype SSL Socket Server - Other - Haxe programming language cookbook

Thanks, I think snake-server gives a full example of running a web server in sys targets, so I’m set for that. My problem in this case is figuring out how to integrate with tink_http.

I am at the point where I’m just going to bolt onto snake-server with a routing system, support for query params, post variables, json serialization and maybe tink async stuff.

I believe tink_tcp worked on sys targets (to some extent) last time I checked

That’s entirely possible, but there’s a serious lack of examples or any help on how to do it.

The examples that come with tink_web and tink_http show NodeJs and Php as containers, but the TcpContainer expects handler callbacks that perform all the work, and I can’t figure it out (and I’m usually pretty good at figuring things out).

Appreciate the replies!

On the lower parts of its stack, tink has a few things that aren’t all that maintained, i.e. tink_runloop and tink_tcp. They are somewhat abandonded, because the compiler team started adding these things to the stdlib (with the event loop and at some point the asynchronous IO APIs), so it seemed a bit pointless to pour too much energy into it.

That said, the point of tink_http is to define clear abstractions, that can be implemented on top of whatever APIs it is that you want to use. In essence tink_web turns a router object (or object hierarchy) into an IncomingHttpRequest -> Promise<OutgoingHttpResponse>. You don’t even need to use the container abstraction of tink_http if you don’t want to. Use whatever server you want, turn its request abstraction into an IncomingHttpRequest, pass it to tink_web, and write the results back to whatever API your server exposes. Can be node, can be PHP, can be snake-server, could be some Java server, could be that you want to compile your tink_web application to Lua to run directly in nginx. No matter. The point is definitely not to have to start on top of TCP (I mostly did it in the spirit of “because we can”), but rather on top of whatever HTTP server you want to run your code in.

1 Like

Thanks!

Yeah, I sort of figured there would be a way to do it with tink_web.

I ended up adding on to snake-server from scratch rather than trying to understand tink_web

Here’s a blog post I wrote about it.

Thanks for the response. I’m super excited to be working on a web server in Haxe, this is going to be a game changer for my future projects.

2 Likes

Good luck on writing your own web server, it’s a lot of fun and if you need any help I’ve walked the same road, and would be happy to give guidance.

In regards to a full featured web server with the features you want to achieve from the article, go2hx may already suit your needs for many of them. As an example:

Requirements:

  • Haxe preview 1 (Likely to be bumped to a nightly Haxe version soon)
  • Hashlink to run the resulting code.
  • Working Hxcpp for the compiler.

Install and setup go2hx running these commands:

haxelib git hxcpp https://github.com/haxefoundation/hxcpp
haxelib git go2hx https://github.com/go2hx/go2hx

Run this command where your project lives, it will by default create a golibs folder at the directory you run the command:

haxelib run go2hx net/http

Then after following the instructions to create an hxml linked to the generated HXB file, you can run this code as Main.hx:

Main.hx

import go.net.http.Http;

function main() {
    Http.handleFunc("/hello", (response, request) -> {
        // ✅ read post form value
        final postFormValue = request.postFormValue("keypostform");
        // ✅ read query value
        final queryValue = request.uRL.query()["queryKey"];
        // ✅ redirects
        Http.redirect(response, request, "/new", statusFound);
    });
    Http.handleFunc("/new", (response, request) -> {
        // ✅ handle methods in a separate manner
        switch request.method.toString() {
            case "GET", "POST", "PUT":
            default:
                // etc...
        }
        // ✅ cookie handling
        final cookieObj = request.cookie("nameOfCookie");
        final cookieValue = cookieObj._0;
        final cookieError = cookieObj._1;
        if (cookieError == null) {
            trace("cookie's value:", cookieValue.value);
            response.write("cookie found: "+ cookieValue.value + " : " + request.method);
        }else{
            // likely cookie not found
            response.write("no cookie found: " + request.method);
        }
    });
    // ✅ Static file serving
    // turn Dir into an interface, Dir -> FileSystem
    final fileHandler = go.Go.asInterface(("." : Dir));
    // "/" handle
    Http.handle("/", Http.fileServer(fileHandler));
    // starting web server
    trace("starting!");
    Http.listenAndServe(":3000", null);
}

This same process can also be achieved for oauth2, memorycache etc. I hope it might be the game changer you seek!

4 Likes

@PXshadow How about performance of this server compared to go?

Fair question, the performance is substantially worse at the moment, it’ll hold up for a few thousand connections, but past that, it’s not capable enough, unlike Go being able to do a million concurrent connections with low latency.

The reason why is 2 fold:

  1. Most importantly, the concurrency model in go2hx is not as scalable as Go, relying on 1 thread per Goroutine model. Go on the other hand uses coroutines + threads model with a very sophisticated scheduler to share work and reduce the resources and maximum CPU usage across all threads.
  2. go2hx has had very little work done on optimizing the outputted Haxe code. The practical reason why, is it’s a large project with few hands working on it. We’ve had to focus on correctness over everything else to get this far.

However there is some good news, on why go2hx is still worth trying out.

  • go2hx is married to Haxe, and Haxe is getting what is shaping out to be a well engineered coroutine system into the language for Haxe 5.
  • go2hx is still young, only getting a working web server in August of this year.
  • It’s Haxe code, and open source. Optimizations will be found and it will reach closer parity with Go with more usage + contributions.

@alex_dja I hope that gives a good overview.

3 Likes

Yep, thank you for detailed disclosure of the topic :+1:

Weblink looks interesting, thanks.

I’ve read a bit about go2hx in the past, and will have to keep an eye on it, thanks!

1 Like