connect-es
connect-es copied to clipboard
Unix domain socket
Is your feature request related to a problem? Please describe.
With other gRPC libraries, I'm able to connect to a gRPC server listening on a unix domain socket (e.g. unix:///path/to/server.sock
).
Describe the solution you'd like
I don't think this is possible with createGrpcTransport()
at the moment, but it would be awesome if it was.
Describe alternatives you've considered
At the moment, I have to use another gRPC client library - I'd prefer to use @bufbuild/connect
instead.
Unfortunately, the Node.js http2
module does not support UDS out of the box. I assume that it's possible to support this, but it's likely not completely trivial.
In general, we aim to not replicate every gRPC feature, and rely on the standard library of the underlying platform. If Node.js were to support UDS in http2.connect
, we'd be happy to make any necessary changes (I assume we'll need to treat baseUrl
a bit differently).
If someone comes up with a reliable alternative to http2.connect
- demonstrated with a code example - we would also be happy to integrate it, or accept contributions.
I may be missing something, but I believe http2
supports UDS. I copied this example from the docs and changed it to bind to a file instead of a port:
import * as http2 from 'node:http2'
const server = http2.createServer()
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html charset=utf-8',
':status': 200,
})
stream.end('<h1>Hello World</h1>')
})
// server.listen(8000)
server.listen('./example.sock')
$ curl -v --http2-prior-knowledge --unix-socket ./example.sock http://test
* Trying ./example.sock:0...
* Connected to test (./example.sock) port 80 (#0)
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: http]
* h2h3 [:authority: test]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x13d80a800)
> GET / HTTP/2
> Host: test
> user-agent: curl/7.88.1
> accept: */*
>
< HTTP/2 200
< content-type: text/html; charset=utf-8
< date: Thu, 31 Aug 2023 08:56:53 GMT
<
* Connection #0 to host test left intact
<h1>Hello World</h1>
I'm glad you brought up the example, Jacob - I should have been more precise. Yes, you can listen to an UDS with an http2
server (it's a method inherited from net
). There is no equivalent for H2 clients though - http2.connect
only accepts URLs with the http or https scheme out of the box, see here.
Ah, fun. So it looks like createConnection
exists in http2.ClientSessionOptions
, this appears to work:
http2.connect('http://example', {
createConnection: (authority, option) => {
return net.connect('./example.sock');
},
})
It looks like it's also possible to pass that as an option to new Http2SessionManager(..., ..., {createConnection})
- perhaps that would just work?
Yup, I can confirm that this works on Linux. Using @connectrpc/connect-node
version 2.0.0-alpha1
import { createGrpcTransport } from "@connectrpc/connect-node";
import { connect as nodeConnect } from "node:net";
const socket = "/path/to/socket"
const transport = createGrpcTransport({
httpVersion: "2",
baseUrl: "http://socket.localhost", // not a real URL, socket is in nodeOptions.createConnection
nodeOptions: {
createConnection: () => {
return nodeConnect(socket)
},
},
})