Networking
There are many ways to talk to other peers. In automerge-repo
this is captured by the NetworkAdapter
interface. Unlike StorageAdapter
s a repository can have many (or zero) NetworkAdapter
s.
"network" is quite a broad term in automerge-repo
. It really means "any other instance of Repo
which I am communicating with by message passing". This means that as well as network adapters for obvious things like websockets, we also implement network adapters for less traditional channels such as MessageChannel
or BroadcastChannel
.
Websockets
The websocket NetworkAdapter
has two parts. This is because the websocket protocol requires a server and a client. The parts are named NodeWSServerAdapter
and BrowserWebsocketClientAdapter
, but don't take these names too seriously, they will both work in a browser or in Node.
Server
The server side of the adapter is NodeWSServerAdapter
, which should be used in combination with the ws
library.
import { WebSocketServer } from "ws";
import { NodeWSServerAdapter } from "@automerge/automerge-repo-network-websocket";
const wss = new WebSocketServer({ port: 8080 });
const adapter = new NodeWSServerAdapter(wss);
Usage with express
Often you aren't running the websocket server as a standalone thing but instead as part of an existing HTTP server. Here's an example of such a situation in an express
app.
import { WebSocketServer } from "ws";
import { NodeWSServerAdapter } from "@automerge/automerge-repo-network-websocket";
import express from "express";
const wss = new WebSocketServer({ noServer: true });
const server = express();
server.on("upgrade", (request, socket, head) => {
wss.handleUpgrade(request, socket, head, (socket) => {
wss.emit("connection", socket, request);
});
});
const adapter = new NodeWSServerAdapter(wss);
server.listen(8080);
Client
The client side of the connection is BrowserWebsocketClientAdapter
.
import { BrowserWebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
const network = new BrowserWebSocketClientAdapter("ws://localhost:3030");
MessageChannel
@automerge/automerge-repo-network-messagechannel
is a NetworkAdapter
for communicating between processes within the same browser using a MessageChannel
.
import { MessageChannelNetworkAdapter } from "@automerge/automerge-repo-network-messagechannel";
import { Repo } from "@automerge/automerge-repo";
const { port1: leftToRight, port2: rightToLeft } = new MessageChannel();
const rightToLeft = new MessageChannelNetworkAdapter(rightToLeft);
const leftToRight = new MessageChannelNetworkAdapter(leftToRight);
const left = new Repo({
network: [leftToRight],
});
const right = new Repo({
network: [rightToLeft],
});
BroadcastChannel
@automerge/automerge-repo-network-broadcastchannel
is a NetworkAdapter
for commuicating between processes in the same browser using a BroadcastChannel
. This will in general be quite inefficient because the sync protocol is point-to-point so even though BroadcastChannel
is a broadcast channel, we still have to duplicate each message for every peer in the channel. It's better to use MessageChannel
if you can, but BroadcastChannel
is good in a pinch.
import { BroadcastChannelNetworkAdapter } from "@automerge/automerge-repo-network-broadcastchannel";
const network = new BroadcastChannelNetworkAdapter();