Connectivity

Mike Fikes edited this page Nov 2, 2015 · 7 revisions

This page describes Ambly REPL connectivity to a level of detail that is helpful for diagnosing issues that may arise in your environment.

One of the first things to check if having discovery and/or connectivity problems is your OS's firewall settings. If you are using OS X and have it set to "Block all incoming connections" then this will prevent connectivity to apps running in the simulator and it can also affect discovery.

The Ambly REPL establishes network connections originating from your computer and going to your device or simulator. (A USB wired connection to a device is not needed for REPL interaction; once an app is installed on a device a REPL connection can be established purely via Wi-Fi.)

A pair of connections is established:

  1. A WebDAV connection is used to mount a directory in your app's sandbox on the device or simulator. This is used as the ClojureScript compiler's output directory (:output-dir).
  2. A TCP connection is established supporting the evaluating ClojureScript forms entered in the REPL. Compiled JavaScript is sent across this connection to be executed within JavaScriptCore in the app, and responses, as well as any (potentially asynchronous) printed output is sent back across this TCP connection.

When the Objective-C side of the REPL is started, it listens on the first available dynamic port (starting at 49152) for WebDAV with the TCP connection listening on the next subsequently numbered port. If either port is unavailable, the REPL tries the next pair until it finds a pair of ports it can listen on.

The Objective-C side of the REPL advertises the non-localhost IPv4 or IPv6 address so that remote REPLs can attach. But, if you are connecting to a simulator running locally on your computer, 127.0.0.1 or ::1 will be used instead so that long-lived REPL connections can be maintained in the face of your computer's address changing (say, if using a laptop that roams from one Wi-Fi to another.)

The WebDAV IP/port advertisement is made via mDNS (Bonjour) using the _http._tcp.local. mDNS service type. You can use dns-sd on a Mac to diagnose Bonjour issues. In particular dns-sd -B _http._tcp can be used to browse the kinds of advertisements made by Ambly, and if you do, you will see Add or Rmv events where all Ambly mDNS Instance Names start with the prefix "Ambly ", with the suffix being the name of the app and other distinguishing info like the name of the simulator type and computer hostname or device name.

Note that, with OS X 10.10 up to 10.10.3, a problematic discoveryd process was included, which could cause mDNS issues. This was rectified by eliminating it with 10.10.4.

The WebDAV endpoint is mounted using the OS's WebDAV client support. For OS X the mount point appears under /Volumes on your filesystem, with the mount point being prefixed by Ambly- and ending in a 8-nybble hexadecimal representing a hash of of the WebDAV URL. An example: /Volumes/Ambly-B65AF28D. When OS X is used to connect, the mount point will also show up under the Shared section of Finder. The WebDAV endpoint is automatically unmounted by Ambly when you quit the REPL (by either typing :cljs/quit or hitting Ctrl-D).

If you encounter problems with Ambly mounting the webdav mount point, see the section at the end of this page for troubleshooting tips.

When files are written to the WebDAV mount, it is normal for warnings and errors to appear in the Xcode console like these:

[WARNING] Unknown DAV property requested "quota-available-bytes"
[ERROR] Error while writing to socket 19: Broken pipe (32)

Since the WebDAV mount point is used for ClojureScript compiler output, all JavaScript output is guaranteed to be on the device (or simulator) when it needs to be loaded into JavaScriptCore. So, for example, if you evaluate (require 'foo.core) at the REPL, src/foo/core.cljs will be compiled (if needed), with the JavaScript, source mapping and other metadata being sent do the device's WebDAV mount, followed by it being loaded by the Objective-C side into JavaScriptCore. The compiler is efficient at only compiling what is needed; thus it is possible to load extremely large namespaces (or large dependency graphs if :reload-all is used).

Any REPL S-expression evaluation results and printed output (println, etc.) is muxed onto the same TCP channel. So, for example, if you have very large results being printed, this may block the ability to evaluate an expression and see its result until the printing is finished.

If the app running on a simulator or device is cycled, then the Ambly REPL will need to be restarted in order to reëstablish connectivity.

Manually testing WebDAV mount on OS X

If you get an error like Unable to mount WebDAV at http://127.0.0.1:49155 try the following, replacing the URL in the example below.

mkdir /Volumes/TestAmbly
mount_webdav http://127.0.0.1:49155 /Volumes/TestAmbly

This will cause OS X to mount the WebDAV mount point just like Ambly would do, but you'll have an opportunity to see if any errors are emitted by the mount_webdav command. If it succeeds try

cd /Volumes/TestAmbly
ls

You should see ambly_repl_deps.js and other directories like cljs, goog, etc.

When done you can issue

umount /Volumes/TestAmbly/

Sometimes, OS X will get into a state where the mount point that Ambly attempts to use is stale or misbehaves, preventing Ambly from using mount_webdav to establish a mount. (You can confirm this by attempting to manually mount the same point.) If this occurs, one way to fix things is to use sudo and remove the problematic mount point. And for really problematic mount point issues, a reboot along with manually clearing stale mount points can get things back in working order.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.