Getting the port number of serve/servlet when running on an ephemeral port

Dear all,

I've trouble finding this in the documentation.
Suppose I start the racket web framework as follows:

(serve/servlet
             (λ (req) (web-serve h req))
             #:listen-ip "127.0.0.1"
             #:port 0
             #:command-line? #t
             #:servlet-path ""
             #:stateless? #t
             #:servlet-regexp #rx"")
            )))

In this case the server will listen on a port the OS chooses.

How do I get the port number it listens on?

The serve procedure accepts a confirmation channel which can give you the port. I don’t think it’s available for some of the higher-level forms, though.

Here’s an example use from my code. It’s relatively easy to combine with dispatch/servlet to do what some of the other interfaces do.

It might be nice if the other interfaces had this ability though.

Thanks Ben, I looked at your code and have managed to use the confirmation channel in my code. I just get the first value of it and that's the port number. Just a question:

  (match (async-channel-get port-ch)
    [(? port-number? port) (values (~a "http://" (best-interface-ip-address) ":" port) stop)]
    [(? exn? e) (raise e)]))

What are you doing here exactly?

The second case exists because the server might fail to start, in which case the channel will get an exception value instead of a port number. Here's an example of a program that will produce such an exception (as long as you run it with normal privileges):

#lang racket
(require web-server/web-server
         racket/async-channel)

(define ach
  (make-async-channel))
(define stop
  (serve #:confirmation-channel ach
         #:port 80 ;<-- needs privileges
         #:dispatch void))
(begin0 (sync ach)
  (sleep 1)
  (stop))
1 Like

Philip covered the need to dispatch on whether we get a port or an exception. The only other thing I think you might be asking is "what is going on with that URL construction?"—the code that starts this server wants to tell the user 2 things:

  • how to access the resulting website on a LAN (to play with friends); and
  • how to stop the server.