UNPKG

@cocalc/project

Version:
130 lines (113 loc) 4.15 kB
/* Handle a general message from the hub. These are the generic message, as opposed to the messages specific to "client" functionality such as database queries. */ import { getLogger } from "@cocalc/project/logger"; import { Message } from "./types"; import * as message from "@cocalc/util/message"; import handleNamedServer from "@cocalc/project/named-servers"; const { exec_shell_code } = require("@cocalc/project/exec_shell_code"); // Reading and writing files to/from project and sending over socket const { read_file_from_project, write_file_to_project, } = require("@cocalc/project/read_write_files"); const { print_to_pdf } = require("@cocalc/project/print_to_pdf"); import processKill from "@cocalc/backend/misc/process-kill"; const { handle_save_blob_message } = require("@cocalc/project/blobs"); const client = require("@cocalc/project/client"); import { version } from "@cocalc/util/smc-version"; import writeTextFileToProject from "./write-text-file-to-project"; const winston = getLogger("handle-message-from-hub"); export default function handleMessage(socket, mesg: Message) { winston.debug("received a message", { event: mesg.event, id: mesg.id, "...": "...", }); // We can't just log this in general, since it can be big. // So only uncomment this for low level debugging, unfortunately. // winston.debug("received ", mesg); if (client.client?.handle_mesg(mesg, socket)) { return; } switch (mesg.event) { case "heartbeat": winston.debug(`received heartbeat on socket '${socket.id}'`); // Update the last hearbeat timestamp, so we know socket is working. socket.heartbeat = new Date(); return; case "ping": // ping message is used only for debugging purposes. socket.write_mesg("json", message.pong({ id: mesg.id })); return; case "named_server_port": handleNamedServer(socket, mesg); return; case "project_exec": // this is no longer used by web browser clients; however it *is* used by the HTTP api served // by the hub to api key users, so do NOT remove it! // The web browser clients use the websocket api, exec_shell_code(socket, mesg); return; case "read_file_from_project": read_file_from_project(socket, mesg); return; case "write_file_to_project": write_file_to_project(socket, mesg); return; case "write_text_file_to_project": writeTextFileToProject(socket, mesg); return; case "print_to_pdf": print_to_pdf(socket, mesg); return; case "send_signal": if ( mesg.pid && (mesg.signal == 2 || mesg.signal == 3 || mesg.signal == 9) ) { processKill(mesg.pid, mesg.signal); } else { if (mesg.id) { socket.write_mesg( "json", message.error({ id: mesg.id, error: "invalid pid or signal (must be 2,3,9)", }) ); } return; } if (mesg.id != null) { // send back confirmation that a signal was sent socket.write_mesg("json", message.signal_sent({ id: mesg.id })); } return; case "save_blob": handle_save_blob_message(mesg); return; case "error": winston.error(`ERROR from hub: ${mesg.error}`); return; case "hello": // No action -- this is used by the hub to send an initial control message that has no effect, so that // we know this socket will be used for control messages. winston.info(`hello from hub -- sending back our version = ${version}`); socket.write_mesg("json", message.version({ version })); return; default: if (mesg.id != null) { // only respond with error if there is an id -- otherwise response has no meaning to hub. const err = message.error({ id: mesg.id, error: `Project does not implement handling mesg with event='${mesg.event}'`, }); socket.write_mesg("json", err); } else { winston.debug(`Dropping unknown message with event='${mesg.event}'`); } } }