-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstandalone-server.js
More file actions
134 lines (111 loc) · 4.68 KB
/
standalone-server.js
File metadata and controls
134 lines (111 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* This is a standalone Reactotron relay server.
*
* TODO:
* * Store full info about a client in here so we can pass it along to connected Reactotron apps.
*
*/
const connectedReactotrons = []
const connectedClients = []
function addReactotronApp(socket) {
// Add the Reactotron app to the list of connected Reactotron apps
connectedReactotrons.push(socket)
// Send a message back to the Reactotron app to let it know it's connected
socket.send(JSON.stringify({ type: "reactotron.connected" }))
console.log("Reactotron app connected: ", socket.id)
// Send the updated list of connected clients to all connected Reactotron apps
const clients = connectedClients.map((c) => ({ clientId: c.clientId, name: c.name }))
connectedReactotrons.forEach((reactotronApp) => {
reactotronApp.send(JSON.stringify({ type: "connectedClients", clients }))
})
}
function forwardMessage(message, server) {
// Forward to the Reactotron Core Server to send to client(s)
server.send(message.type, message.payload, message.clientId)
}
function interceptMessage(incoming, socket, server) {
const message = JSON.parse(incoming.toString())
if (message.type === "reactotron.sendToCore") {
const { payload } = message
const { type, ...actualPayload } = payload
server.wss.clients.forEach((wssClient) => {
if (wssClient.clientId === payload.clientId) {
wssClient.send(
JSON.stringify({
type,
payload: actualPayload,
}),
)
}
})
return
}
if (connectedReactotrons.includes(socket)) forwardMessage(message, server)
if (message.type === "reactotron.subscribe") addReactotronApp(socket)
}
function startReactotronServer(opts = {}) {
const { createServer } = require("reactotron-core-server")
// configure a server
const server = createServer({
port: opts.port || 9292, // default
...opts,
})
server.start()
server.wss.on("connection", (socket, _request) => {
// Intercept messages sent to this socket to check for Reactotron apps
socket.on("message", (m) => interceptMessage(m, socket, server))
})
// The server has started.
server.on("start", () => console.log("Reactotron started"))
// A client has connected, but we don't know who it is yet.
// server.on("connect", (conn) => console.log("Connected", conn))
// A client has connected and provided us the initial detail we want.
server.on("connectionEstablished", (conn) => {
// Add the client to the list of connected clients if it's not already in the list
if (!connectedClients.find((c) => c.clientId === conn.clientId)) connectedClients.push(conn)
const clients = connectedClients
connectedReactotrons.forEach((reactotronApp) => {
// conn here is a ReactotronConnection object
// We will forward this to all connected Reactotron apps.
// https://github.com/infinitered/reactotron/blob/bba01082f882307773a01e4f90ccf25ccff76949/apps/reactotron-app/src/renderer/contexts/Standalone/useStandalone.ts#L18
reactotronApp.send(JSON.stringify({ type: "connectedClients", clients }))
})
})
// A command has arrived from the client. (Maybe?)
server.on("command", (cmd) => {
// send the command to all connected Reactotron apps
connectedReactotrons.forEach((reactotronApp) => {
console.log("Sending command to Reactotron app: ", cmd.type, reactotronApp.id)
reactotronApp.send(JSON.stringify({ type: "command", cmd }))
})
})
// A client has disconnected.
server.on("disconnect", (conn) => {
console.log("Disconnected", conn)
// Forward the disconnect to all connected Reactotron apps
connectedReactotrons.forEach((reactotronApp) => {
// conn here is a ReactotronConnection object
// We will forward this to all connected Reactotron apps.
// https://github.com/infinitered/reactotron/blob/bba01082f882307773a01e4f90ccf25ccff76949/apps/reactotron-app/src/renderer/contexts/Standalone/useStandalone.ts#L18
reactotronApp.send(JSON.stringify({ type: "disconnect", conn }))
})
// Remove the client from the list of connected clients
const delIndex = connectedClients.findIndex((c) => c.clientId === conn.clientId)
if (delIndex !== -1) connectedClients.splice(delIndex, 1)
})
// The server has stopped.
server.on("stop", () => console.log("Reactotron stopped"))
// Port is already in use
server.on("portUnavailable", () => console.log(`Port ${opts.port} unavailable`))
// check to see if it started
if (!server.started) {
console.log("Server failed to start")
return
}
// stop the server on SIGINT (metro shutdown)
process.on("SIGINT", () => {
server.stop()
process.exit(0)
})
}
module.exports = { startReactotronServer }