UNPKG

@foxglove/ws-protocol-examples

Version:

Foxglove WebSocket protocol examples

136 lines 5.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const rosmsg_serialization_1 = require("@foxglove/rosmsg-serialization"); const ws_protocol_1 = require("@foxglove/ws-protocol"); const commander_1 = require("commander"); const debug_1 = tslib_1.__importDefault(require("debug")); const ws_1 = require("ws"); const boxen_1 = tslib_1.__importDefault(require("../boxen")); const setupSigintHandler_1 = require("./util/setupSigintHandler"); const log = (0, debug_1.default)("foxglove:service-server"); debug_1.default.enable("foxglove:*"); async function main() { const supportedEncodings = ["json", "ros1"]; const server = new ws_protocol_1.FoxgloveServer({ name: "service-server", capabilities: [ws_protocol_1.ServerCapability.services], supportedEncodings, }); const port = 8765; const ws = new ws_1.WebSocketServer({ port, handleProtocols: (protocols) => server.handleProtocols(protocols), }); (0, setupSigintHandler_1.setupSigintHandler)(log, ws); const serviceDefRos = { name: "/set_bool_ros", type: "std_srvs/SetBool", request: { encoding: "ros1", schemaName: "std_srvs/SetBool_Request", schemaEncoding: "ros1msg", schema: "bool data", }, response: { encoding: "ros1", schemaName: "std_srvs/SetBool_Response", schemaEncoding: "ros1msg", schema: "bool success\nstring message", }, }; const serviceDefJson = { name: "/set_bool_json", type: "std_srvs/SetBool", request: { encoding: "json", schemaName: "SetBoolJsonRequest", schemaEncoding: "jsonschema", schema: JSON.stringify({ $schema: "https://json-schema.org/draft/2019-09/schema", type: "object", properties: { data: { type: "boolean" }, }, }), }, response: { encoding: "json", schemaName: "SetBoolJsonResponse", schemaEncoding: "jsonschema", schema: JSON.stringify({ $schema: "https://json-schema.org/draft/2019-09/schema", type: "object", properties: { success: { type: "boolean" }, message: { type: "string" }, }, }), }, }; const serviceById = new Map([ [server.addService(serviceDefRos), serviceDefRos], [server.addService(serviceDefJson), serviceDefJson], ]); ws.on("listening", () => { void (0, boxen_1.default)(`📡 Server listening on localhost:${port}. To see data, visit:\n` + `https://app.foxglove.dev/~/view?ds=foxglove-websocket&ds.url=ws://localhost:${port}/`, { borderStyle: "round", padding: 1 }).then(log); }); ws.on("connection", (conn, req) => { const name = `${req.socket.remoteAddress}:${req.socket.remotePort}`; log("connection from %s via %s", name, req.url); server.handleConnection(conn, name); }); server.on("serviceCallRequest", (request, clientConnection) => { const service = serviceById.get(request.serviceId); if (!service) { const err = new Error(`Received invalid serviceId: "${request.serviceId}"`); server.sendServiceCallFailure({ op: "serviceCallFailure", serviceId: request.serviceId, callId: request.callId, message: err.message, }, clientConnection); throw err; } if (service.request.encoding !== request.encoding) { const err = new Error(`Service ${service.name} called with invalid message encoding. Expected ${service.request.encoding}, got ${request.encoding}`); server.sendServiceCallFailure({ op: "serviceCallFailure", serviceId: request.serviceId, callId: request.callId, message: err.message, }, clientConnection); throw err; } log("Received service call request with %d bytes", request.data.byteLength); const responseMsg = { success: true, message: `Service ${service.name} successfully called`, }; let responseData = new Uint8Array(); if (request.encoding === "json") { responseData = new Uint8Array(Buffer.from(JSON.stringify(responseMsg))); } else { const definitions = [ { name: "success", type: "bool" }, { name: "message", type: "string" }, ]; const writer = new rosmsg_serialization_1.MessageWriter([{ definitions }]); responseData = writer.writeMessage(responseMsg); } const response = { ...request, data: responseData, }; server.sendServiceCallResponse(response, clientConnection); }); server.on("error", (err) => { log("server error: %o", err); }); } exports.default = new commander_1.Command("service-server") .description("advertises a ROS1 and JSON SetBool service that can be called") .action(main); //# sourceMappingURL=service-server.js.map