@blackprint/remote-control
v0.2.0
Published
Blackprint remote control
Downloads
25
Readme
Blackprint - Remote Control
This module will provide an ability for Blackprint to control engine remotely and can be used for multi-user collaboration
⚠️ Production Warning This module is not intended for production use without proper security measures. If you plan to ship this feature in a production environment, you must implement:
- Sandboxed Environment: Isolate the remote control functionality in a secure sandbox
- Permission-Based System: Implement proper authentication and authorization
- Input Validation: Validate all incoming remote commands and data
- Rate Limiting: Prevent abuse and denial-of-service attacks
- Secure Communication: Use encrypted connections and proper certificate validation
Recommendation: Remove this feature entirely from production builds unless you have implemented comprehensive security measures and understand the risks involved. Remote control capabilities can expose your application to significant security vulnerabilities if not properly secured.
Any ports data flow for sketch will be disabled if it's connected to remote engine. It's not recommended to combine different data flow between remote <~> remote in just one instance, you should create two different instance for them and use feature from other module/library to sync data between the two instance itself.
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/scarletsframe.dev.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@blackprint/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/@blackprint/[email protected]/dist/remote-control.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@blackprint/[email protected]/dist/blackprint.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@blackprint/[email protected]/dist/blackprint.sf.js"></script>
<script src="https://cdn.socket.io/4.4.1/socket.io.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@blackprint/[email protected]/dist/blackprint.sf.css">Implementation for browser
Implementation for browser
let instance = new Blackprint.Sketch();
let client = new Blackprint.RemoteSketch(instance);
let socket = new io("http://localhost:2345"); // Replace with your relaying server (Socket.io)
// Add listener in case if the remote sync was disabled
client.on('disabled', ()=> SmallNotif.add("Remote sync was disabled", 'red'));
// instance.syncDataOut = false; // Uncomment this if you don't want to sync browser "node data" to the engine
instance.disablePorts = true; // Uncomment this if you want to disable any data flow on the browser
// Allow import/module sync (you can perform async actions, return true to allow, and return false to disallow)
client.onImport = async v => console.log("Remote import is allowed") || true;
client.onModule = async v => console.log("Remote module is allowed") || true;
// Relay data sync between instance (remote engine and the control)
socket.on('relay', v => client.onSyncIn(v)); // Engine -> Sketch
client.onSyncOut = v => socket.emit('relay', v); // Sketch -> EngineImplementation for server
For the example below with Node.js, you need to install socket.io npm i socket.io.
This is just relaying server with Socket.io, you can customize it with WebRTC or UDP instead. Both RemoteSketch from the browser need to be connected to this same relaying server.
let port = 2345;
let httpServer = require('http').createServer();
let io = require('socket.io')(httpServer, {
cors: { origin: ["http://localhost:6789", "https://blackprint.github.io"]}
});
io.on('connection', client => {
client.on('relay', data => client.broadcast.emit('relay', data));
console.log("A client was connected");
client.on('disconnect', ()=> console.log("A client got disconnected"));
});
console.log(`Waiting connection on port: ${port}`);
httpServer.listen(port);You must change Blackprint.RemoteSketch with Blackprint.RemoteControl if you want to remote control only the engine (RemoteSketch is used if you want to control remote sketch).
let { createServer } = require("http");
let { Server } = require("socket.io");
let port = 2345;
let httpServer = createServer();
let io = new Server(httpServer, {
cors: { origin: ["http://localhost:6789", "https://blackprint.github.io"]}
});
Blackprint.allowModuleOrigin('*'); // Allow load from any URL (localhost/https only)
let instance = new Blackprint.Engine();
let remote = new Blackprint.RemoteEngine(instance);
// Allow import/module sync (return true = allow, false = disable sync)
remote.onImport = v=> console.log("Remote import is allowed") || true;
remote.onModule = v=> console.log("Remote module is allowed") || true;
// "Blackprint.onModuleConflict" need to be replaced if you want to use this to solve conflicting nodes
// Use below if you want to always use the newest module
// Blackprint.onModuleConflict = async map => Object.entries(map).forEach(v => v.useOld = false);
let engineStartup = Date.now();
io.on('connection', client => {
// Relay data sync between instance (remote engine and the control)
client.on('relay', data => remote.onSyncIn(data)); // Sketch -> Engine
remote.onSyncOut = data => client.emit('relay', data); // Engine -> Sketch
console.log('Remote control: connected');
client.on('disconnect', () => console.log('Remote control: disconnected'));
});
console.log(`Waiting connection on port: ${port}`);
httpServer.listen(port);License
MIT License
