diff --git a/jjava-jupyter/src/main/java/org/dflib/jjava/jupyter/channels/JupyterSocket.java b/jjava-jupyter/src/main/java/org/dflib/jjava/jupyter/channels/JupyterSocket.java index 15d34cb..cfa64b8 100644 --- a/jjava-jupyter/src/main/java/org/dflib/jjava/jupyter/channels/JupyterSocket.java +++ b/jjava-jupyter/src/main/java/org/dflib/jjava/jupyter/channels/JupyterSocket.java @@ -39,8 +39,14 @@ public abstract class JupyterSocket extends ZMQ.Socket { + /** + * Builds a ZeroMQ endpoint for a channel from the connection file properties. For the {@code ipc} transport, + * Jupyter treats {@code ip} as a base path and names each channel socket {@code "{ip}-{port}"} + * (this is what {@code jupyter_client} writes and what frontends connect to). + */ protected static String formatAddress(String transport, String ip, int port) { - return transport + "://" + ip + ":" + port; + String separator = "ipc".equalsIgnoreCase(transport) ? "-" : ":"; + return transport + "://" + ip + separator + port; } // Comes from a Python bytestring diff --git a/jjava-jupyter/src/test/java/org/dflib/jjava/jupyter/channels/JupyterSocketTest.java b/jjava-jupyter/src/test/java/org/dflib/jjava/jupyter/channels/JupyterSocketTest.java new file mode 100644 index 0000000..932ebe1 --- /dev/null +++ b/jjava-jupyter/src/test/java/org/dflib/jjava/jupyter/channels/JupyterSocketTest.java @@ -0,0 +1,19 @@ +package org.dflib.jjava.jupyter.channels; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class JupyterSocketTest { + + @Test + public void formatAddress_tcp() { + assertEquals("tcp://127.0.0.1:54321", JupyterSocket.formatAddress("tcp", "127.0.0.1", 54321)); + } + + @Test + public void formatAddress_ipc() { + // Jupyter convention: "ip" is a base path, channel sockets are "{ip}-{port}" + assertEquals("ipc:///tmp/kernel-abc-1", JupyterSocket.formatAddress("ipc", "/tmp/kernel-abc", 1)); + } +}