Skip to content

Commit

Permalink
RPC Sample with custom reply queue
Browse files Browse the repository at this point in the history
  • Loading branch information
kum-deepak committed Apr 18, 2021
1 parent 933e981 commit c40b30d
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 5 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ See the client at:
- [rpc/simple/rx-rpc.html](rpc/simple/rx-rpc.html).
- Click the button `Submit Problem` many times to see each one getting submitted
as independent requests.
- There is an alternate client sample at
[rpc/simple/rx-rpc-explicit-return-dest.html](rpc/simple/rx-rpc-explicit-return-dest.html).
This uses custom reply queue. This client is only tested with the simple ruby server.

You will need to run at least one of the following servers:

Expand Down
13 changes: 10 additions & 3 deletions rpc/ruby-server/simple-server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
# rpc-server-thread-pool.rb
###############################################################################


amqp_conn = Bunny.new
amqp_conn.start

Expand All @@ -29,13 +28,21 @@

# Process the request, compute the response
operands = JSON.parse(payload)
result = {result: operands['x'].to_i + operands['y'].to_i}
result = { result: operands['x'].to_i + operands['y'].to_i }
response_body = result.to_json
# Completed processing

puts "RPC Server: Response: #{response_body} for #{payload}"

default_exchange = channel.default_exchange

default_exchange.publish response_body, routing_key: metadata[:reply_to], correlation_id: metadata[:correlation_id]
reply_to = metadata[:reply_to]

# if the RPC client uses explicit queue name for replies, it needs to be translated from STOMP
# semantics to AMQP. In this just removing the prefix /queue/ is sufficient
# See https://www.rabbitmq.com/stomp.html#d for details
reply_to = reply_to.sub(%r{^/queue/}, '')

puts "Sent with routing key: #{reply_to}"
default_exchange.publish response_body, routing_key: reply_to, correlation_id: metadata[:correlation_id]
end
150 changes: 150 additions & 0 deletions rpc/simple/rx-rpc-explicit-return-dest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple RPC Application using RxStompRPC and RxJS</title>
<link type="text/css" rel="stylesheet" href="../../assets/style.css">
</head>
<body>
<div id="wrapper">
<ul>
<li>You will need a STOMP broker running. The defaults will work for fresh RabbitMQ on local machine.</li>
<li>Adjust the <a href="https://stomp-js.github.io/api-docs/latest/classes/RxStompConfig.html">configuration</a>
as per your STOMP broker.
</li>
<li>For details on API calls see:
<a href="https://stomp-js.github.io/api-docs/latest/classes/RxStompRPC.html">
API Reference</a>
</li>
<li>
This example uses <a href="https://www.rabbitmq.com/stomp.html#d">queue destination of RabbitMQ</a>. The queue must be created before running the sample.
The ruby server creates the queue if it is not there.
</li>
<li>Start the server by opening <a href="rx-rpc-server.html">RPC Server</a> in another browser tab/window.</li>
<li>Alternatively run any of the Ruby servers, see README for details.</li>
<li>
Clicking on submit will generate two rand integers and send to RPC server endpoint.
</li>
<li>
Click submit multiple times, you can see the results reaching back in different order than it was submitted.
</li>
<li>
See guide at
<a href="https://stomp-js.github.io/guide/rx-stomp/ng2-stompjs/2018/10/12/remote-procedure-call.html">
https://stomp-js.github.io/guide/rx-stomp/ng2-stompjs/2018/10/12/remote-procedure-call.html</a>
</li>
</ul>

<div id="chatbox"></div>

<button name="submitproblem" id="submitproblem">Submit Problem</button>
</div>

<!-- It is used for DOM manipulation, not mandatory to use stompjs -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>

<!-- Include from CDN for better performance, alternatively you can locally copy as well -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/bundles/rxjs.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@stomp/stompjs@6/bundles/stomp.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@stomp/rx-stomp@1/bundles/rx-stomp.umd.min.js"></script>

<script type="application/javascript">
// Helper function to generate random integers
function randomInt(max) {
return Math.floor(Math.random() * max);
}

// Destination is RabbitMQ specific, change as per your environment
const rpcEndPoint = '/amq/queue/integer-addition';

// This is the RPC client
$(function () {
let rxStomp;

const stompConfig = {
// Typically login, passcode and vhost
// Adjust these for your broker
connectHeaders: {
login: "guest",
passcode: "guest"
},

// Broker URL, should start with ws:// or wss:// - adjust for your broker setup
brokerURL: "ws://localhost:15674/ws",

// Keep it off for production, it can be quit verbose
// Skip this key to disable
debug: function (str) {
console.log('STOMP: ' + str);
},

// Log raw data sent/received
logRawCommunication: true,

heartbeatIncoming: 20000,
heartbeatOutgoing: 20000,

// If disconnected, it will retry after 200ms
reconnectDelay: 5000,
};

// Create an instance. The first RxStomp is the UMD module name and other is the class name
rxStomp = new RxStomp.RxStomp();

const stompRPCConfig = {
// A name unique across all clients
replyQueueName: `/queue/replies-${randomInt(1000000000)}`,

// Simply subscribe, you would need to secure by adding broker specific options
setupReplyQueue: (replyQueueName, rxStomp) => {
return rxStomp.watch(replyQueueName, {
durable: false,
'auto-delete': true,
'exclusive': true
});
},
};

// RPC Client
const rxStompRPC = new RxStomp.RxStompRPC(rxStomp, stompRPCConfig);

// You can set additional configuration here
rxStomp.configure(stompConfig);

// Attempt to connect
rxStomp.activate();

// Set the DOM event handlers must not be inside onConnect - other for each reconnect it will keep getting added
$("#submitproblem").click(function () {
if (!rxStomp.connected) {
alert("Broker disconnected, can't send message.");
return;
}

const x = randomInt(200);
const y = randomInt(200);

// Display the problem on screen
const msgDiv = displayProblem(x + " + " + y);

// The RPC call returns an Observable which will trigger only once
rxStompRPC.rpc({
destination: rpcEndPoint,
body: JSON.stringify({x: x, y: y})
}).subscribe(function (result) {
const output = JSON.parse(result.body).result;
msgDiv.find('.solution').html(output);
});
});

function displayProblem(problem) {
const msgDiv = $("<div>").addClass("msgln");
msgDiv.html('<span class="problem">[' + problem + ']: </span><span class="solution">waiting...</span>');
$("#chatbox").append(msgDiv);
msgDiv[0].scrollIntoView();
return msgDiv;
}
})
</script>
</body>
</html>
6 changes: 5 additions & 1 deletion rpc/simple/rx-rpc-server.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ <h1>Simple RPC Server</h1>
<li>Adjust the <a href="https://stomp-js.github.io/api-docs/latest/classes/RxStompConfig.html">configuration</a>
as per your STOMP broker.
</li>
<li>
This example uses <a href="https://www.rabbitmq.com/stomp.html#d">queue destination of RabbitMQ</a>. The queue must be created before running the sample.
The ruby server creates the queue if it is not there.
</li>
<li>
The server endpoint will wait for a random period (max 1000ms) before responding.
</li>
Expand Down Expand Up @@ -110,4 +114,4 @@ <h1>Simple RPC Server</h1>
});
</script>
</body>
</html>
</html>
6 changes: 5 additions & 1 deletion rpc/simple/rx-rpc.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
<a href="https://stomp-js.github.io/api-docs/latest/classes/RxStompRPC.html">
API Reference</a>
</li>
<li>
This example uses <a href="https://www.rabbitmq.com/stomp.html#d">queue destination of RabbitMQ</a>. The queue must be created before running the sample.
The ruby server creates the queue if it is not there.
</li>
<li>Start the server by opening <a href="rx-rpc-server.html">RPC Server</a> in another browser tab/window.</li>
<li>Alternatively run any of the Ruby servers, see README for details.</li>
<li>
Expand Down Expand Up @@ -123,4 +127,4 @@
})
</script>
</body>
</html>
</html>

0 comments on commit c40b30d

Please sign in to comment.