TCP driver for qmux, then explored Scripting Bridge schemas and libobjc
Tags: typescript, node, websockets, devlog
Published: 2018-09-21 13:24:07

---
title: TCP driver for qmux, then explored Scripting Bridge schemas and libobjc
published: true
description: Today I had the boring task of writing a TCP driver for qmux. I got it working and also working to power qrpc. I started on a better WebSocket driver, but ran out of steam. But then I was pulled down a rabbit hole around Scripting Bridge stuff, learning where all the Apple framework schemas are stored and learned about libobjc.
tags: typescript, nodejs, websockets, devlog
---

Today I came back to my [qmux](https://github.com/progrium/prototypes/blob/master/qmux/SPEC.md) implementation for Node.js and the browser. Since it's been a while, qmux is a stream multiplexing protocol extracted from SSH. I use it primarily for qrpc, the foundation of my distributed object system. 

The goal for today was to write a TCP connection driver using Node's standard library. I like having a TCP implementation that won't need any libraries to use it. 

It's been a while since I've worked with the Node net module and it was not fun. I ended up referencing some libraries that wrap them with promise APIs since my system is designed around async/await and promises for basic sanity.

I got a TCP qmux demo working, and then I tested it under qrpc. It didn't work, but the problem ended up being something I figured out in the qmux implementation working with buffers of binary data. This is quite tricky in JavaScript as you might imagine. 

So, then I decided to go back and build a better driver around WebSocket using what seemed like a more popular Node.js library. I'm still surprised they aren't part of the standard library. After playing with it for a while I decided when I come back to this I'll just use the library I'm more familiar with; it doesn't really matter that much. 

There are a lot of uses for this, but I wanted to be able to use qrpc to communicate from JXA apps. Among other ideas, I could export the bridged Objective-C API in the JXA environment; sort of like the Python and Ruby Objective-C bridges. Thinking about this led me to look and find the bridge support files I'd read about that come with all the Apple frameworks. Sure enough, they have giant XML files describing their entire API.

Some of the existing bridges have helpful docs on this format, and I eventually found official Apple docs. This led me to discover libobjc. I think I knew of this the last time I read about the Scripting Bridge stuff, but seeing it used via FFI made me realize how cool it is to have a C library interface into an object-oriented runtime. 

I decided it was impossible there was no Go bridge yet. So, I dug around more than last time. I found a couple projects that were all over 5 years old and not completed. One of them had a pretty great Go API wrapper for libobjc, but all the framework APIs were being added by hand. I think I could easily generate those APIs with the Scripting Bridge schemas. 

And then, I guess what's funny is I wouldn't be that interested in using JXA if I could use Objective-C APIs from Go. The AppleScript APIs would still be nice, and it might still be easiest to re-expose those via qrpc from JXA. We'll see.

{% youtube zjj_oXRk5A4 %}