diff --git a/cf.js b/cf.js
index 860be38f127fb8c735a25eda3d86e88e461faf84..52d0d2ab9825e3c09cde31fc7b9e8f6a70f34fa3 100644
--- a/cf.js
+++ b/cf.js
@@ -12,6 +12,7 @@ const {
   Worker, workerData
 } = require('worker_threads')
 // will use these to figure where tf we are
+let ownIp = ''
 const os = require('os')
 let ifaces = os.networkInterfaces()
 
@@ -82,18 +83,23 @@ app.get('/pipeHookup/:file', (req, res) => {
   // we can assume that the file is a reciprocal pipe-type in our local pipes/file.js location
   // we'll open that can as a spawn, can assume it's hosting a websocket (it will tell us the port?)
   // and we can send that information back up stream,
-  console.log('/pipes', req.params.file)
+  // every time we get one of these, we should find & nuke any of the same name
+  // to restart,
+  // that way, remote clients can attempt a reset by issuing the same request
+  // and report server-down if nothing happens
   const piper = new Worker(`${__dirname}/pipes/${req.params.file}`)
   piper.on('message', (msg) => {
-    console.log('worker msg', msg)
+    if(msg.startup){
+      console.log('worker for /pipeHookup/' + req.params.file + ' resolves')
+      res.send({startup: true, ip: ownIp, port: msg.port})
+    }
   })
   piper.on('error', (err) => {
     console.log('worker err', err)
   })
   piper.on('exit', (code) => {
-    console.log('exit code', code)
+    console.log('worker exit code', code)
   })
-  res.send({address: 'localip', port: '1024'})
   // then this (or similar) should be all we really need to add here, and we can do local-dev of the pipes in hunks/pipes/pipename.js and pipes/pipename.js
   // so, do we spawn, or do we use workers ?
   // awh yis it's workers, messages easy, errors also OK to catch... nextup: draw the sys, what wraps what doesn't? mostly: want to be able to refresh / reload / restart remotely
@@ -112,6 +118,7 @@ Object.keys(ifaces).forEach(function(ifname) {
       // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
       return;
     }
+    ownIp = iface.address
     if (alias >= 1) {
       console.log('cf available on: \t' /*ifname + ':' + alias,*/ + iface.address + `:${port}`);
       // this single interface has multiple ipv4 addresses
diff --git a/hunks/pipes/pipetemplate.js b/hunks/pipes/pipetemplate.js
index 9a7c5f3740c72ff4535a60de8d3772ae9c416149..a4896ec00fe79e1b5dfb4d46f720864c064c86ff 100644
--- a/hunks/pipes/pipetemplate.js
+++ b/hunks/pipes/pipetemplate.js
@@ -22,9 +22,32 @@ export default function Pipe() {
 
   // coming merge of init and onload, however:
   this.init = () => {
+    startWsConnection()
+  }
+
+  let ws = {}
+
+  let startWsConnection = () => {
     // hijack ajax to ask for a websocket
     jQuery.get('pipeHookup/pipetemplate.js', (data) => {
-      console.log('pipe jquery data', data)
+      if (data.startup) {
+        console.log('serverside launched, starting client')
+        console.log(data)
+        // have data.ip and data.port
+        ws = new WebSocket(`ws://${data.ip}:${data.port}`)
+        ws.onopen = (evt) => {
+          console.log('vfpt opens', evt)
+        }
+        ws.onerror = (evt) => {
+          console.log('vfpt error', evt)
+        }
+        ws.onclose = (evt) => {
+          console.log('vfpt close', evt)
+        }
+        ws.onmessage = (msg) => {
+          console.log('vfpt recv', msg)
+        }
+      }
     })
   }
 
diff --git a/package-lock.json b/package-lock.json
index 39be1bd6f0baef176a4febceb7a74eef86401c76..159fd640ad28b9d376682723a4e1705a26467f75 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,11 @@
       "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
       "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
     },
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+    },
     "body-parser": {
       "version": "1.19.0",
       "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
@@ -367,6 +372,14 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
       "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+    },
+    "ws": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.2.tgz",
+      "integrity": "sha512-gftXq3XI81cJCgkUiAVixA0raD9IVmXqsylCrjRygw4+UOOGzPoxnQ6r/CnVL9i+mDncJo94tSkyrtuuQVBmrg==",
+      "requires": {
+        "async-limiter": "^1.0.0"
+      }
     }
   }
 }
diff --git a/pipes/pipetemplate.js b/pipes/pipetemplate.js
index 913ae0271e9d5709c8f67cef1e3e7b6f92f8c314..3f1ab2ee8f251635b674bfd9f600d4e28a47bc15 100644
--- a/pipes/pipetemplate.js
+++ b/pipes/pipetemplate.js
@@ -2,4 +2,17 @@ const {
   parentPort
 } = require('worker_threads')
 
-parentPort.postMessage('hello worker')
+const WebSocketServer = require('ws').Server
+
+let port = 2042
+const WSS = new WebSocketServer({port: port}, () => {
+  parentPort.postMessage({
+    startup: true,
+    port: port
+  })
+})
+
+WSS.on('connection', (ws) => {
+  console.log('ws connects')
+  // ...
+})