Is it possible to use a Subject in ZeroMQ? - zeromq

I have a little project that implements NATS Queueing
This is the code:
import * as NATS from '../node_modules/nats' // for typescript
var nats = require('nats');
var config = require('./config');
var opt: NATS.ClientOpts = {'noRandomize': false, 'reconnect': true,
'maxReconnectAttempts': -1, 'servers':config.nat.servers, 'user':
config.nat.user , 'pass': config.nat.pass };
var nc: NATS.Client = nats.connect(opt);
nc.on('error', function(e) {
console.error('Error nats: ' + e);
});
nc.on('close', function() {
console.error('CLOSED nats');
});
nc.subscribe('serviceA', { 'queue': 'A' }, function (request, replyTo) {
console.debug('I exec serviceA via nats:');
j = JSON.parse(request);
console.debug(j);
let ok = {"res": "i am response for service A"}
nc.publish(replyTo, JSON.stringify(ok));
}
let cmd = '{"a": 5, "b": "i am sample"}';
nc.requestOne('serviceA', cmd, {}, 15000, function (response) {
if (response.code && response.code === nats.REQ_TIMEOUT) {
console.error('server timeout');
console.error(response.code);
} else {
console.log('A see this response: ' + response);
}
});
nc.subscribe('serviceB', { 'queue': 'B' }, function (request, replyTo) {
console.debug('I exec serviceB via nats:');
j = JSON.parse(request);
console.debug(j);
let ok = {"res": "i am response for service B"}
nc.publish(replyTo, JSON.stringify(ok));
}
let cmd = '{"c": 5, "d": "i am sample"}';
nc.requestOne('serviceB', cmd, {}, 15000, function (response) {
if (response.code && response.code === nats.REQ_TIMEOUT) {
console.error('server timeout');
console.error(response.code);
} else {
console.log('B see this response: ' + response);
}
});
As you can see, there are 2 services - serviceA on queue A and serviceB on queue B and 2 clients: the first calls service A and the second calls service B
NATS implements Subject ( 'serviceA' and 'serviceB' )
Now, I want try to convert the example using ØMQ I found a similar sample using ZeroMQ
But I can find nothing sample on Subject.
Perhaps ØMQ uses ROUTER so as to implements a subject
Can you help me to implement subject into a ZeroMQ example?

Q: Is it possible to use a Subject in ZeroMQ?A: Yes, it is:
The long story short - one does not need any zmq.ROUTER for doing this, just use a PUB / SUB formal pattern.
Beware: ZeroMQ Socket()-instance is not a tcp-socket-as-you-know-it.
Best
read about the main conceptual differences in [ ZeroMQ hierarchy in less than a five seconds ] Section.
The Publisher side:
import zmq
aCtx = zmq.Context()
aPub = aCtx.Socket( zmq.PUB )
aPub.bind( "tcp://123.456.789.012:3456" )
aPub.setsockopt( zmq.LINGER, 0 )
aPub.setsockopt( zmq.<whatever needed to fine-tune the instance>, <val> )
i = 0
while true:
try:
aPub.send( "ServiceA::[#{0:_>12d}] a Hello World Message.".format( i ) )
aPub.send( "ServiceABCDEFGHIJKLMNOPQRSTUVWXYZ........" )
aPub.send( "ServiceB::[#{0:_>12d}] another message...".format( i / 2 ) ) if ( i == ( 2 * ( i / 2 ) ) ) else pass
sleep( 1 ); i += 1
except KeyboardInterrupt:
print( "---< will exit >---" )
break
print( "---< will terminate ZeroMQ resources >---" )
aPub.close()
aCtx.term()
The Subscriber side:
import zmq
aCtx = zmq.Context()
aSub = aCtx.Socket( zmq.SUB )
aSub.connect( "tcp://123.456.789.012:3456" )
aSub.setsockopt( zmq.LINGER, 0 )
aSub.setsockopt( zmq.SUBSCRIBE, "ServiceA" ) # Subject ( 'serviceA' and 'serviceB' )
aSub.setsockopt( zmq.SUBSCRIBE, "ServiceB" ) # Kindly see the comments below
# # Kindly see API on subscription management details
#
# # Yet another "dimension"
# # to join ingress
# # from multiple sources
#Sub.connect( "<transport-class>://<addr>:<port>" )
# <transport-class :: { inproc | ipc | tcp | pgm | epgm | vmci }
# .connect()-s the same local SUB-AccessPoint to another PUB-side-AccessPoint
# to allow the PUB/SUB Scalable Formal Communication Archetype Pattern
# join a message flow from different source PUB-sides
#Sub.setsockopt( zmq.SUBSCRIBE, "ServiceZ" )
while true:
try:
print( "<<< (((_{0:s}_)))".format( aSub.recv() ) )
except KeyboardInterrupt:
print( "---< will exit >---" )
break
print( "---< will terminate ZeroMQ resources >---" )
aSub.close()
aCtx.term()

Related

IfIndex calculation Huawei

I'm trying to interface to a Huawei device (MA5608T) via Python through SNMP.I learned that there is a correspondence between the index value and the port.
But I still don't understand how it translates
for example:
4194445056.0(index) = 0/17/7(port)
does anyone know what are the steps to do?
try this way:
4194304000 + (slot * (256 * 32)) + pon * 256) + '.' + onu_id
This Javascript code is taken from production. The binary operations will give you a clue on how to extract the data from the packet.
function convert_snmp_packet( packet ){
let regex = /[^\.]*/g;
let found = packet.match( regex );
if( found.length < 2 ) {
throw new Error( "wrong packet ? " + packet );
}
let left_part = parseInt( found[0] );
// found[1] is just the dot
let ont_index = parseInt( found[ 2 ] );
let slot_num;
let port_num;
slot_num = ( left_part & ( 15 << 13 ) ) >> 13;
port_num = ( left_part & ( 15 << 8 ) ) >> 8;
let json = {
slot_num: slot_num,
port_num: port_num,
ont_index: ont_index
};
return json;
}
test code:
class packet_Test extends Test {
test_packet( ){
// packet must be a String for this to work
let p = "4194445056.0";
let actual = convert_snmp_packet( p );
let expected = { slot_num: 1, port_num: 7, ont_index: 0 };
this.assertEquals( expected, actual );
this.done()
}
}
Sorry for the necromancy. Ran into this while looking for information about SNMP over a Huawei olt.

Does switchmap automatically calls the subscription?

I am trying to obtain a behavior such that if current observable is changed in value, the respective observables linked should be invoked respectively.
The following code works as intended, but I just need some conformation regarding this behavior, I am trying to implement this on production site.
I know switchMap unsubscribes from current subscription and resubscribes to new one that's returned.
But, Does it also call the new observable subscribed to kick in and run the code it has or is this run by the pipe operator or am I missing any crucial concept ?
Can some one kindly, clarify this.
Thank you.
Here is the stackblitz code link ::: https://stackblitz.com/edit/rxjs-ktnf9x :: and Overview
let a = new BehaviorSubject(null);
let b = new BehaviorSubject(null);
let c = new BehaviorSubject(null);
let d = new BehaviorSubject(null);
let a$ = a.asObservable();
let b$ = b.asObservable();
let c$ = c.asObservable();
let d$ = d.asObservable();
d$
.pipe(
switchMap(
data => {
console.log("from d :: " + data);
return c$;
}
)
)
.pipe(
switchMap(
data => {
console.log("from c :: " + data);
return b$;
}
)
)
.pipe(
switchMap(
data => {
console.log("from b :: " + data);
return a$;
}
)
)
.subscribe(
data => {
console.log("from a :: " + data);
console.log(""); // for next line.
}
)
b.next("calls");
a.next("allSubs");
c.next("it");
d.next("does");
d.next('yes');
finally --> Outputs ::: yes it calls allSubs
To make it simpler to explain. SwitchMap unsubscribe c$ when d$ emits. if d emit once and c keeps emitting you will get a sequence of d-c-c-c
if d emits again in the middle you will get d-c-c-c-d-c-c-c
d$
.pipe(
switchMap(
data => {
console.log("from d :: " + data);
return c$;
}
)
)

Index error occurs when trying to use an event listener

I am trying to add a touch event listener to the image object being loaded. Although this is practically an exact copy and paste from the documentation:
https://docs.coronalabs.com/api/type/EventDispatcher/addEventListener.html
It returns the following error:
36: attempt to index local 'object' (a nil value)
local t = {}
local img = {}
local i = 1
local function showImages ()
local function networkListenerImg( event )
if ( event.isError ) then
print ( "Network error - download failed" )
else
event.target.alpha = 0
transition.to( event.target, { alpha = 1.0 } )
end
end
for k,v in pairs(t) do
img[#img + 1] = v
end
local object = display.loadRemoteImage( event.params.chapter .. img[i], "GET", networkListenerImg, img[i], system.TemporaryDirectory, 50, 50 )
function object:touch( event )
if event.phase == "began" then
print( "You touched the object!" )
return true
end
end
object:addEventListener( "touch", object )
end
The table, t, is populated elsewhere in the code and is populated properly.
While you didn't mention which of those lines is line 36 (there are only 28 lines there), I can still see your error. The issue is that object is and always will be nil: display.loadRemoteImage() does not return anything, see this.
What you need to do is have your listener callback capture object, which must be declared before the callback is. The callback should then set the value of object to the results of the download. Like so...
local t = {}
local img = {}
local i = 1
local function showImages ()
local object
local function networkListenerImg( event )
if ( event.isError ) then
print ( "Network error - download failed" )
else
event.target.alpha = 0
transition.to( event.target, { alpha = 1.0 } )
-- fill in code to save the download object into "object"
end
end
for k,v in pairs(t) do
img[#img + 1] = v
end
display.loadRemoteImage( event.params.chapter .. img[i], "GET", networkListenerImg, img[i], system.TemporaryDirectory, 50, 50 )
function object:touch( event )
if event.phase == "began" then
print( "You touched the object!" )
return true
end
end
object:addEventListener( "touch", object )
end

lua corona - How to load an image using loadRemoteImage

I want to load an image from a URL.
I can load an image using this code:
local group = display.newGroup();
local testImg;
testImg = display.newImage( "cells/cellBottom.png");
group:insert( testImg );
but i need to use something like:
testImg = display.loadRemoteImage( "https://www.dropbox.com/s/fqlwsa5gupt5rsj/amcCells.png")
group:insert( testImg );
Please tell me how to load this image.
Cheers :)
Just use example given in Corona. This works with the following url but your url seems to have problem.
local function networkListener( event )
if ( event.isError ) then
print ( "Network error - download failed" )
else
event.target.alpha = 0
transition.to( event.target, { alpha = 1.0 } )
end
print ( "event.response.fullPath: ", event.response.fullPath )
print ( "event.response.filename: ", event.response.filename )
print ( "event.response.baseDirectory: ", event.response.baseDirectory )
end
display.loadRemoteImage( "http://coronalabs.com/images/coronalogogrey.png", "GET", networkListener, "coronalogogrey.png", system.TemporaryDirectory, 50, 50 )
try add yougroup:insert(event.target) in listener
local function networkListener( event )
if ( event.isError ) then
print ( "Network error - download failed" )
else
event.target.alpha = 0
transition.to( event.target, { alpha = 1.0 } )
**yourgroup:insert(event.target)**
end
print ( "event.response.fullPath: ", event.response.fullPath )
print ( "event.response.filename: ", event.response.filename )
print ( "event.response.baseDirectory: ", event.response.baseDirectory )
end
display.loadRemoteImage( "http://coronalabs.com/images/coronalogogrey.png", "GET", networkListener, "coronalogogrey.png", system.TemporaryDirectory, 50, 50 )

Array of buses in superCollider

I have a Synth generated with a do:
(
SynthDef(\siny, { arg freq, outBus=0; Out.ar( outBus, SinOsc.ar(freq!2,0,0.2) ) } ).send(s);
SynthDef(\filter, { arg cFreq,q=0.8, inBus; Out.ar( 0, BPF.ar(In.ar(inBus), cFreq!2, 1/q ) ) } ).send(s);
)
(
~sourceOut = Bus.audio(s);
~sine_Group = ParGroup.new;
z = [100,500,1000,1500,250];
{
z.do({ arg val; Synth.head(~sine_Group, \siny, [\freq: val, \outBus: ~sourceOut]) });
z.do({ arg val; Synth.after(~sine_Group, \filter, [\inBus: ~sourceOut, \cFreq: 200] ) });
}.play;
)
Right now, my understanding is that, output of multiple instances of Synth \siny get mixed in the bus ~sourceOut, and goes as an input into synth \filter
What i actually want to do is to have a one-to-one connection between the multiple instances of \siny and \filter.. Could I use an array of busses to connect them? If so, how do I do that?
Yes you can. Here I've modified your code minimally. First I made ~sourceOut an array of Busses rather than a single Bus. Second, inside the do loops I made use of the fact that the main iteration functions in SuperCollider can provide a second index argument as well as each item itself. Thirdly I use that index argument to select the desired Bus:
(
z = [100,500,1000,1500,250];
~sourceOut = z.collect{ Bus.audio(s) };
~sine_Group = ParGroup.new;
{
z.do({ arg val, index; Synth.head(~sine_Group, \siny, [\freq: val, \outBus: ~sourceOut[index]]) });
z.do({ arg val, index; Synth.after(~sine_Group, \filter, [\inBus: ~sourceOut[index], \cFreq: 200] ) });
}.play;
)
Depending on your needs, you might also like to look at NodeProxy which is useful for prototyping and live coding, and provides some tricks for plugging synths' output into each other.

Resources