Repository: bokeh/bokeh

Issue:
[BUG] Serve application at random port failed
Hello,

since Bokeh 2.1.0 (windows 10), trying to serve an application with random port (--port=0) does not work anymore and result in the following error:
```
(py37) D:\PythonWorkspace\divers>bokeh serve C:\Users\xa235208\Downloads\bokeh-master\examples\app\sliders.py --show --port=0
2020-06-16 09:39:45,845 Starting Bokeh server version 2.1.0 (running on Tornado 6.0.4)
2020-06-16 09:39:45,847 User authentication hooks NOT provided (default user enabled)
2020-06-16 09:39:45,850 Bokeh app running at: http://localhost:61622/sliders
2020-06-16 09:39:45,850 Starting Bokeh server with process id: 14652
2020-06-16 09:39:46,587 Refusing websocket connection from Origin 'http://localhost:61622';                       use --allow-websocket-origin=localhost:61622 or set BOKEH_ALLOW_WS_ORIGIN=localhost:61622
to permit this; currently we allow origins {'localhost:0'}
```


Discussion:
If this is local usage then `--allow-websocket-origin="*"` is a potential workaround for now. Not sure when/how this got introduced. 
Most likely it was this PR https://github.com/bokeh/bokeh/pull/10070 the port added to the `allowlist` is the original passed-in `opts.port`, not the value returned from `bind_sockets`

https://github.com/bokeh/bokeh/pull/10070/files#diff-35e262b3fd4a971d380038e009fd69acR398
This diff fixes, but any PR needs to come with a test
```
diff --git a/bokeh/server/server.py b/bokeh/server/server.py
index 78f19bbe8..97eec3965 100644
--- a/bokeh/server/server.py
+++ b/bokeh/server/server.py
@@ -395,7 +395,7 @@ class Server(BaseServer):
         sockets, self._port = bind_sockets(opts.address, opts.port)
         self._address = opts.address

-        extra_websocket_origins = create_hosts_allowlist(opts.allow_websocket_origin, opts.port)
+        extra_websocket_origins = create_hosts_allowlist(opts.allow_websocket_origin, self.port)
         try:
             tornado_app = BokehTornado(applications,
                                        extra_websocket_origins=extra_websocket_origins,
```

Resolving patch:
diff --git a/bokeh/server/server.py b/bokeh/server/server.py
--- a/bokeh/server/server.py
+++ b/bokeh/server/server.py
@@ -395,7 +395,7 @@ def __init__(self, applications, io_loop=None, http_server_kwargs=None, **kwargs
         sockets, self._port = bind_sockets(opts.address, opts.port)
         self._address = opts.address
 
-        extra_websocket_origins = create_hosts_allowlist(opts.allow_websocket_origin, opts.port)
+        extra_websocket_origins = create_hosts_allowlist(opts.allow_websocket_origin, self.port)
         try:
             tornado_app = BokehTornado(applications,
                                        extra_websocket_origins=extra_websocket_origins,


Test patch:
diff --git a/tests/unit/bokeh/test_client_server.py b/tests/unit/bokeh/test_client_server.py
--- a/tests/unit/bokeh/test_client_server.py
+++ b/tests/unit/bokeh/test_client_server.py
@@ -165,6 +165,10 @@ async def check_http_blocked_socket_blocked(self, server, origin=None):
     async def test_allow_websocket_origin(self, ManagedServerLoop) -> None:
         application = Application()
 
+        # allow good local origin with random port
+        with ManagedServerLoop(application, port=0) as server:
+            await self.check_http_ok_socket_ok(server, origin="http://localhost:%s" % server.port)
+
         # allow good origin
         with ManagedServerLoop(application, allow_websocket_origin=["example.com"]) as server:
             await self.check_http_ok_socket_ok(server, origin="http://example.com:80")