CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/sync-client/scratch/primus.ts
Views: 687
1
/*
2
Create a very, very simple example using the nodejs ws library of a client
3
and server talking to each other via a websocket. The client and server
4
should both be nodejs processes (no web browser involved!).
5
6
The simple code below works fine and accomplishes the goal above.
7
8
In one node shell:
9
10
> require('./dist/primus').server();
11
Server Received message: hi
12
13
In another:
14
15
> socket = require('./dist/primus').client();
16
> Client Received message: Welcome to the WebSocket server!
17
> socket.write("hi")
18
undefined
19
*/
20
21
import Primus from "primus";
22
import http from "http";
23
import { join } from "path";
24
import * as responder from "@cocalc/primus-responder";
25
import * as multiplex from "@cocalc/primus-multiplex";
26
27
export function server() {
28
const httpServer = http.createServer((_req, res) => {
29
res.end("Hello from the server!");
30
});
31
32
const primus = new Primus(httpServer, { transformer: "websockets" });
33
34
primus.on("connection", (socket) => {
35
console.log("Client connected");
36
socket.write("Welcome to the server!");
37
38
socket.on("data", (data) => {
39
console.log(`Received from client: ${data}`);
40
});
41
});
42
43
httpServer.listen(8080, () => {
44
console.log("Server listening on port 8080");
45
});
46
}
47
48
export function client() {
49
const primus = Primus.createSocket({ transformer: "websockets" });
50
const socket = new primus("http://localhost:8080");
51
52
socket.on("open", () => {
53
console.log("Connected to server");
54
socket.write("Hello from the client!");
55
56
socket.on("data", (data) => {
57
console.log(`Received from server: ${data}`);
58
});
59
});
60
61
return socket;
62
}
63
64
/*
65
connect to a specific project (bypassing the proxy) for now, so
66
we can flesh this out.
67
68
> c = require('./dist/primus').project({appBasePath:'/10f0e544-313c-4efe-8718-2142ac97ad11/port/5000',project_id:'97ce5a7c-25c1-4059-8670-c7de96a0db92', port:34491})
69
> c.writeAndWait({cmd:'exec',opts:{command:'pwd'}}, console.log)
70
undefined
71
> {
72
stdout: '/home/user/cocalc/src/data/projects/97ce5a7c-25c1-4059-8670-c7de96a0db92\n',
73
stderr: '',
74
exit_code: 0
75
}
76
77
With this, we can make a proof of concept of a remote Jupyter
78
kernel. Then we have to worry about authentication.
79
*/
80
81
export function project({
82
appBasePath,
83
project_id,
84
port,
85
}: {
86
appBasePath: string;
87
project_id: string;
88
port: number;
89
}) {
90
const url = `http://127.0.0.1:${port}`;
91
const opts = {
92
pathname: join(appBasePath, project_id, "raw/.smc/ws"),
93
transformer: "websockets",
94
plugin: { responder, multiplex },
95
} as const;
96
const primus = Primus.createSocket(opts);
97
const socket = new primus(url);
98
99
socket.on("open", () => {
100
console.log("Connected to project");
101
socket.on("data", (data) => {
102
console.log(`Received from server: ${data}`);
103
});
104
});
105
106
return socket;
107
}
108
109