The following connects the js client to all the existent hubs:
$.connection.hub.start({ transport: 'longPolling' }).done(function () {});
Is there some way to connect to some particular hub instead?
If not, what is the point of "OnConnected()" and "OnDisconnected()" being in EVERY hub? if all of them are going to be called anyway.
I'm asking this because there is a particular html (something like a news feed) in which I want to handle notifications from one hub (when news are posted, this view should handle and show them appearing). I'm going to use groups but seems more natural to separate this in hubs.
You only subscribe to hubs that you have client side events associated with. So lets say you had two hubs:
hubA
hubB
In your client if you have:
var hubA = $.connection.hubA;
hubA.client.foo = function() {};
$.connection.hub.start();
You will only be subscribed to events on hubA (not hubB).
You can choose to use or not use the connection events in any hubs you create. You certainly can separate your code into logical sections using hubs, no harm in that.
var connection = $.hubConnection(server);
var someHub= connection.createHubProxy("someHub");
connection.start({transport: 'longPolling'}).done(function () {})
Related
I need to subscribe to server events from client, so syntax is
Hub.client.[my event here]= function
It's working, but what if I need to subscribe with params, i.e. user need to see only unread messages or a list of messages with a criteria. So I want the same event subscription with modifiers. Like :
Hub.subscribe.messages({read:true}) = function ....
At server side I want to push updates only for clients that subscribed to this type of criteria and specific parameters.
I know I can make groups of clients but that seems to be overhead and not best practice.
I've used the client syntax:
Hub.client["MethodName_" + dynamicParam] = function
And server side syntax:
HubContext.Clients.All.Invoke(string.Format("MethodName_{0}", dynamicParam), data);
That way I can register to dynamic events based on the client selection of "dynamicParam"
I asked a question in:
Microservice Architecture dependency which pattern to use when using a clustered Microservice architecure.
I recieved answer that point to point should work but when reading:
https://nats.io/documentation/concepts/nats-req-rep/
It feels like all subscribers recieves event (and because of that handles it) but there will just be one subscriber that responses. This will not work when putting an order event that will trigger an update-inventory-event that Inventory microservices subscribes to (as in example in link) i.e it wont work in a clustered env due to inventory will be updated the same amount of times as the amount of microservice instances.
How can I solve this scenario using Nats?
Thanks in advance!
NATS.io supports this feature using queue groups:
All subscriptions with the same queue name will form a queue group.
Each message will be delivered to only one subscriber per queue group,
using queuing semantics. You can have as many queue groups as you wish.
Normal subscribers will continue to work as expected.
Connect your services using the queue group (sample is node.js):
https://github.com/nats-io/node-nats#queue-groups
nats.subscribe('foo', {'queue':'job.workers'}, function() {
received += 1;
});
then the client would use the library provided request methods:
https://github.com/nats-io/node-nats#basic-usage
// Request for single response with timeout.
nats.requestOne('help', null, {}, 1000, function(response) {
// `NATS` is the library.
if(response.code && response.code === NATS.REQ_TIMEOUT) {
console.log('Request for help timed out.');
return;
}
console.log('Got a response for help: ' + response);
});
Having the following code on the server:
Meteor.publish(null, function(){
// Return some cursors.
})
will according to the documentation have the following effect: the record set is automatically sent to all connected clients.
How can I on the client side determine if all the documents published by this function has been received? If I would use a subscription instead, it would provide me with a ready callback, letting me know when all the documents been received. What's the matching way here? Or are the documents already received at the client when my client side code starts to execute?
I'm afraid there's no way to have a ready callback for so called universal subscriptions you mentioned above. Just have a look at this part of Meteor's code, where the publish and subscription logic is defined on the server. For convenience I'm copy/pasting the code below:
ready: function () {
var self = this;
if (self._isDeactivated())
return;
if (!self._subscriptionId)
return; // unnecessary but ignored for universal sub
if (!self._ready) {
self._session.sendReady([self._subscriptionId]);
self._ready = true;
}
}
The _subscriptionId is only given to named subscriptions, which are those that you would manually define using Meteor.subscribe method. The subscriptions corresponding to null publish functions, doesn't have their own _subscriptionId, so as you can see from the code above, the server is not event trying to send the ready message to the client.
I'm kind of new to web development and I became a fan of meteor because of the way it lets me do cool stuf really easy. I have been toying around with the parties example and I have added a date attribute for the parties. I would like to only subscribe the client to parties that have not yet expired.
Essentially where datenow < partydate.
I find myself stuck in writing the correct subscribe code as I only find documentation on how to subscribe based on database attributes and not based on comparing the date of the party with the current date.
Meteor.subscribe("parties"); --> I think this is the part of the code on the client that I need to edit.
I really hope somebody could show me in the right direction on writing the correct subscribe code.
The client subscribes to what the server is willing to send to them.
if(Meteor.isClient){
Meteor.subscribe("parties");
}
The server filters data the client shouldn't have, typically for security reasons. You wouldn't want passwords or private information being published. Any client can open up the console and browse the full data set that was published to them.
if(Meteor.isServer){
Meteor.publish("parties", function(){
return Parties.find({date: {$gt: Date.now()}});
});
}
If you want clients to be able to see both expired parties and non-expired parties, you would publish the whole set from the server, then filter it on the client in a template helper.
if(Meteor.isServer){
Meteor.publish("parties", function(){
return Parties.find();
});
}
if(Meteor.isClient){
Meteor.subscribe("parties");
Template.templateName.allParties = function(){
return Parties.find();
}
Template.templateName.activeParties = function(){
return Parties.find({date: {$gt: Date.now()}});
}
}
Can I create a new conference room (Asterisk ConfBridge) through Asterisk Manager Interface (AMI)? Help me please!
This response is for anyone who has struggled as me to do this, even if the first response and the comments to it may be enough.
So, you can originate a conference call, with the action Originate and the application ConfBridge (as far as i know, it comes with Asterisk, not independent).
You can see all the available fields here http://www.voip-info.org/wiki/view/Asterisk+Manager+API+Action+Originate
I will throw an example without every field, but the ones I know and needed on my app.
This is what you throw at the Asterisk Manager Interface, if you want to call someone into a conference, then add someone else (without the comments ofc.)
Action: Originate // The action type
ActionID: CreateConf-1 // This id will be linked to further events about the action
Channel: SIP/1001 // The sipId of the peer u wanna call
Timeout: 30000 // If he doesnt respons in 30000ms, drop it
CallerID: Asterisk // The id of the caller (will be seen on target phone)
Application: ConfBridge // The application
Async: true // (NOT SURE, MAYBE BULLSHIT) If false, i think you can no longer originate while he hasn't answered
Data: 1234 // Very important, this is like the conference id, will detail above
Action: Originate
ActionID: CreateConf
Channel: SIP/1000
Timeout: 30000
CallerID: Asterisk
Application: ConfBridge
Async: true
Data: 1234
So with this, one block at time, two guys will be called into a conference.
As you saw the Data field represents the identifier of the call, so if you wanna give your conference an id, use it. This way you could create and manage different conferences.
Since i work with NAMI (the nodejs library for Asterisk Manager Interface) (https://github.com/marcelog/Nami), let me also drop you how to do thanks to the lib.
var namiLib = require('nami');
var namiInstance = new (namiLib.Nami)(config); // See more about config (and everything else about nami) in their docs
namiInstance.open();
var action = new namiLib.Actions.Originate();
action.channel = 'SIP/1000';
action.data = '12345'; // my conferenceId
action.timeout = 30000;
action.callerID = 'Metisse\'s king';
action.application = 'ConfBridge';
action.async = true;
namiInstance.send(action, function (response) {
// deal with the response
});
Obviously, if you need to use NAMI to have control other Asterisk, you have to do something more generic to handle sending your actions and validating them, also watching for errors.
You can use dynamic conference(without room exist) feature and create calls using Originate command to application Confbridge.
No. You can use an AMI redirect to transfer your call to a piece of dialplan code that would read a channel variable, database look up or some other mechanism to set up a new conference, however.
For a full list of AMI actions for ConfBridge, please see: https://wiki.asterisk.org/wiki/display/AST/ConfBridge+10#ConfBridge10-ConfBridgeAsteriskManagerInterface(AMI)Actions