This example includes ready-to-use client-side and server-side libraries for performing REST / AJAX / RPC-style communication over SMQ. The code enables fast and simple server-side method calls directly from a browser, without page reloads.
At a conceptual level, REST, AJAX, and RPC (Remote Procedure Calls) all describe ways for a browser to talk to a server asynchronously. The names come from different eras and communities, but the underlying idea is the same: the client sends a request, the server performs some work, and the result is returned without blocking the user interface.
In short:
- AJAX describes how the browser sends requests (background, asynchronous)
- REST and RPC describe how the API is modeled
- The runtime behavior is essentially the same
Although this example uses an RPC-style programming model (calling named server methods), it fulfills the same role as REST APIs in practice. Many real-world REST APIs are effectively RPC expressed through URLs and HTTP verbs. The difference here is primarily one of expression, not capability.
SMQ is a lightweight, message-based communication layer designed for low-latency, bidirectional messaging between browsers and servers. It avoids HTTP request overhead and is well suited for interactive applications where responsiveness matters.
From a high-level perspective, the SMQ RPC plugin follows the same fundamental approach described in the AJAX over WebSockets tutorial, but uses SMQ instead of raw WebSockets. With SMQ, you get both asynchronous publish/subscribe messaging and AJAX-style method calls from the browser to the server, all within a single, unified communication model.
SMQ is designed for messaging, not for large payloads. The maximum SMQ payload size is 2^16 - 15. In addition, the SMQ RPC plugin incurs some overhead; thus, a recommended maximum size is 65,400 bytes.
If you need to send larger chunks of data, use LSP pages or the REST plugin.
Call server methods directly from the browser.
This example demonstrates REST/RPC-style communication over SMQ using client- and server-side libraries. From JavaScript, you call server functions as if they were local methods. Under the hood, the calls are sent asynchronously to the server, and results are returned without blocking the UI.
The result is:
- Very fast request/response handling (faster than HTTP-based REST)
- Simple, readable client code
- No conceptual difference from REST or AJAX-based APIs, just a more direct programming model
If you are comfortable with REST or AJAX, RPC over SMQ will feel familiar. It is the same interaction pattern, expressed in a way that emphasizes calling server logic rather than manipulating URLs.
This JavaScript library provides a simple way to perform RPC-style calls over SMQ. It abstracts message handling and exposes server-side functions as asynchronous JavaScript methods.
- Dynamic proxy creation: Automatically generates proxies for remote procedure calls
- Asynchronous communication: Uses Promises for non-blocking operations
- Error handling: Clean propagation of server-side and connection errors
To use the library, you need an smq object configured for your SMQ messaging environment. Pass this object to createSmqRpc to initialize the RPC mechanism.
let smq = {/* Your SMQ configuration here */};
let smqRpc = createSmqRpc(smq);
// smqRpc includes: proxy and disconnect()
const rpc = smqRpc.proxy;
smq.onclose = () => {
// Rejects all pending RPC calls so callers do not hang
smqRpc.disconnect();
};Each RPC call returns a Promise.
rpc.yourMethodName("Hello", "World")
.then(response => {
console.log("Response:", response);
})
.catch(error => {
console.error("RPC Error:", error);
});async function example() {
try {
const response = await rpc.yourMethodName("Hello", "World");
console.log("Response:", response);
} catch (error) {
console.error("RPC Error:", error);
}
}
example();Both styles are functionally identical. async / await is simply modern syntax built on top of Promises and is often easier to read as applications grow.
The Lua library handles server-side RPC logic. Functions registered here are exposed automatically to connected clients.
-- Define a function that corresponds to 'yourMethodName'
function yourMethodName(arg1, arg2)
trace("yourMethodName called with arguments:", arg1, arg2)
-- For illustration, concatenate the arguments
local result = arg1 .. " " .. arg2
return result -- "Hello World"
end
smq = require "smq.hub".create()
require "smqrpc".create(smq, {
yourMethodName = yourMethodName
})Start the example using the Mako Server:
cd LSP-Examples/SMQ-examples
mako -l::RPC
| .preload - Server example code
| index.html - Client example code
| smqrpc.js - Client RPC library
|
\---.lua
smqrpc.lua - Server RPC library