MESSAGE requests (instant messaging), then register it in the Message Dispatcher next to the Connect processor.
A Processor receives every SIP message as a protobuf MessageRequest, decides where it goes, and returns the modified message. It is the last stop before EdgePort sends the message out. Use one when the built-in Connect processor doesn’t fit, for example to build an IM service, SCAIP logic, or an IoT integration.
Prerequisites
- Node.js and npm.
- A running Routr core: an EdgePort, a Message Dispatcher, and a Location Service. Running Routr from source gives you all three.
- Familiarity with the message flow.
The processor contract
Every Processor implements one RPC, defined inprocessor.proto:
@routr/processor hands you the request as JSON. This excerpt shows the shape of a REGISTER:
Build the IM processor
1
Create the project
Create a folder and install the Processor library, the Location Service client, and
fp-ts for pipe:2
Start the gRPC server
Create
index.js. It connects to the Location Service and starts a Processor on port 51904 that sends REGISTER and MESSAGE to handlers and rejects everything else:index.js
listen() calls your function once per message with the MessageRequest and a Response. You must answer every call with one of the Response methods:3
Handle REGISTER
Create
handlers.js. The register handler stores the sender’s route in the Location Service under the target AOR and replies 200 OK:handlers.js
4
Handle MESSAGE with the Alterations API
Replace the The two branches implement EdgePort cooperation:
sendMessage stub. It forwards responses back, looks up the callee, and builds the outgoing message by piping the request through alterations. Each alteration takes a MessageRequest and returns a modified copy:handlers.js
addSelfVia(route)adds a Via for the egress EdgePort interface.addSelfRecordRoute(route)keeps this EdgePort in the path for the rest of the dialog.addRouteToPeerEdgePort(route)adds a Route to the EdgePort that holds the callee’s connection.addRouteToNextHop(route)adds a Route to the callee.addXEdgePortRefadds theX-Edgeport-Refheader;removeXEdgePortRefstrips it on the last hop.decreaseMaxForwards,removeAuthorization, andremoveSelfRoutesclean up the request before delivery.
5
Run the processor
Start it:The library logs a line like
starting routr service {"name":"instant-messaging","bindAddr":"0.0.0.0:51904"}.Register the processor in the Dispatcher
The Message Dispatcher sends each request to the first processor whosematchFunc returns true and whose methods include the request method. Order matters: put specific matches before catch-alls.
This dispatcher.yaml sends MESSAGE to the IM processor and everything else to Connect:
dispatcher.yaml
matchFunc is a JavaScript expression evaluated against the JSON MessageRequest. Other useful matches:
addr to wherever your processor runs. When you run from source, edit config/dispatcher.yaml and restart with npm run start:dispatcher. On Kubernetes, add the entry under dispatcher.processors in the Helm values.
The Dispatcher is optional. For a single processor you can point EdgePort’s
spec.processor.addr straight at it and list the methods it handles in spec.methods.Verify
Register two softphones (for example Blink) against your EdgePort and send a chat message from one to the other. The message reaches the second phone, and the processor’s console shows the requests it handled. AMESSAGE to an unregistered user returns 404 Not Found.
Pitfalls
- Keep processors stateless. Store state in the Location Service or the API Server, not in memory, so you can run several replicas.
- Answer every call. A handler that throws without calling a
Responsemethod leaves the transaction hanging; wrap handlers intry/catchand callsendInternalServerError(). - Alterations don’t mutate. They return a deep copy, so always send the result of
pipe, not the originalreq.
Related
Alterations API
Every alteration and helper exported by
@routr/processor.Build a middleware
Add side effects before or after the processor.
Message Dispatcher
Full Dispatcher configuration.
Message flow
How a request moves through Routr.