mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-27 14:11:04 +02:00
docs+lnrpc: enable bi-directional WebSockets
The grpc-gateway library that is used to transform REST calls into gRPC uses a different method for reading a request body stream depending on whether the RPC is a request-streaming one or not. We can't really find out what kind of RPC the user is calling at runtime, so we add a new parameter to the proxy that lists all request-streaming RPC calls. In any case the client _has_ to send one request message initially to kick off the request processing. Normally this can just be an empty message. This can lead to problems if that empty message is not expected by the gRPC server. But for the currently existing two client-streaming RPCs this will only trigger a warning (HTLC interceptor) or be ignored (channel acceptor).
This commit is contained in:
@@ -97,3 +97,55 @@ ws.on('message', function(body) {
|
||||
// "height": <int64>,
|
||||
// }
|
||||
```
|
||||
|
||||
## Request-streaming RPCs
|
||||
|
||||
Starting with `lnd v0.13.0-beta` all RPCs can be used through REST, even those
|
||||
that are fully bi-directional (e.g. the client can also send multiple request
|
||||
messages to the stream).
|
||||
|
||||
**Example**:
|
||||
|
||||
As an example we show how one can use the bi-directional channel acceptor RPC.
|
||||
Through that RPC each incoming channel open request (another peer opening a
|
||||
channel to our node) will be passed in for inspection. We can decide
|
||||
programmatically whether to accept or reject the channel.
|
||||
|
||||
```javascript
|
||||
// --------------------------
|
||||
// Example with websockets:
|
||||
// --------------------------
|
||||
const WebSocket = require('ws');
|
||||
const fs = require('fs');
|
||||
const macaroon = fs.readFileSync('LND_DIR/data/chain/bitcoin/simnet/admin.macaroon').toString('hex');
|
||||
let ws = new WebSocket('wss://localhost:8080/v1/channels/acceptor?method=POST', {
|
||||
// Work-around for self-signed certificates.
|
||||
rejectUnauthorized: false,
|
||||
headers: {
|
||||
'Grpc-Metadata-Macaroon': macaroon,
|
||||
},
|
||||
});
|
||||
ws.on('open', function() {
|
||||
// We always _need_ to send an initial message to kickstart the request.
|
||||
// This empty message will be ignored by the channel acceptor though, this
|
||||
// is just for telling the grpc-gateway library that it can forward the
|
||||
// request to the gRPC interface now. If this were an RPC where the client
|
||||
// always sends the first message (for example the streaming payment RPC
|
||||
// /v1/channels/transaction-stream), we'd simply send the first "real"
|
||||
// message here when needed.
|
||||
ws.send('{}');
|
||||
});
|
||||
ws.on('error', function(err) {
|
||||
console.log('Error: ' + err);
|
||||
});
|
||||
ws.on('ping', function ping(event) {
|
||||
console.log('Received ping from server: ' + JSON.stringify(event));
|
||||
});
|
||||
ws.on('message', function incoming(event) {
|
||||
console.log('New channel accept message: ' + event);
|
||||
const result = JSON.parse(event).result;
|
||||
|
||||
// Accept the channel after inspecting it.
|
||||
ws.send(JSON.stringify({accept: true, pending_chan_id: result.pending_chan_id}));
|
||||
});
|
||||
```
|
||||
|
Reference in New Issue
Block a user