I am working on a crm where Jobs are assigned to employees automatically and when a job is created application looks for the employee with maximum idle time.I am able to broad cast notification to all the employees but I want to know how to send notification to the employee for which job is assigned.Just like facebook each user recieves his notifications only.I am using this statement in hub class
Clients.All.broadcastMessage( message);
You are currently broadcasting your messages to everyone I suggest you useClients.User(userid)
Get the current logged in user string userName = HttpContext.Current.User.Identity.Name;
And then to send out notification to the particular user you can have something like.
Clients.User(userName).broadcastMessage(message);
You have to recognize user depending on connectionId.
Here is a good blog post describing this:
http://www.tugberkugurlu.com/archive/mapping-asp-net-signalr-connections-to-real-application-users
I was struggling with this just 3 days ago, and finally got it working.
Suppose you have a Hub class called YourHub, your javascript code should look like this
$(function () {
var yourHub = $.connection.YourHub;
yourHub.client.OnMessage = function ( message) {
console.log(message):
};
});
Then you need to implement IUserIdProvider on the server, which receives a IRequest (there should be a cookie or something for you to identify the person), and implement the method
public string GetUserId(IRequest request)
Then as Izzy told you use Clients.User(userId).OnMessage(message)
where userId is the id you return on the GetUserId and OnMessage is the method in your javascript file.
Be carefull to use Clients.User(userId) not Clients.Client(userId)
Related
So I want to send a message to a specific client via SignalR. That client is not Clients.Caller - currently I can only identify it by let's call it "ID", a property in the context: this.Context.Items["ID"]
So to find a client by its ID, how do I...access all clients or contexts? Or should I save this ID in a different way? This is not the connection ID, it is an ID that maps to something in the database.
Basically I'd like to go Clients.Single(c => c.Items["ID"] == specificId).SendMessage(msg);
In the OnConnectedAsync method in your hub, you can group a user by their "ID" each time they connect.
E.G:
public async override Task OnConnectedAsync()
{
var currentUserId = /*get your current users id here*/
await Groups.AddToGroupAsync(Context.ConnectionId, $"user-{currentUserId}");
await base.OnConnectedAsync();
}
Then when you need to send that person a message, you can just broadcast it to their 'personal' group. (One person may have multiple connections, so the group approach work perfectly for us).
E.G:
Clients.Group($"user-{userId}").SendAsync("UserSpecificMessage", message);
When users disconnect, SignalR will handle the removing of connections from the groups automatically.
In using this approach, we do not have to unnecessarily broadcast a message to every single client with the intention of only one client filtering out the message based on the id.
You can send the ID down to the clients using context.Clients.User(...) or context.Clients.All(). Then in JavaScript, read the ID and compare it to what's on the page. If it's a match, carry out some action; else ignore.
As an example, let's say your app's processing a specific record on an edit screen. The record ID is on the page as a form field. You send a SignalR message down from C# with the ID. You do a comparison in JavaScript between the ID and the form field value; if they match, you display a toaster message, perform other processing, etc.
I have a Bot created with v4 of the Microsoft Bot Framework. I can successfully use this bot in the "Test in Web Chat" portion in the Azure Portal. I can also successfully use this bot in an app that I've created in Microsoft Teams. I now want to send a notification from the "Test in Web Chat" piece to a specific user in Teams. For example, in the "Test in Web Chat" piece, I'd like to enter
Hello someuser#mytenant.com
When this is sent via the "Test in Web Chat" piece, I'd like to show "Hello" in Microsoft Teams to only someuser#mytenant.com. I have successfully tokenized the string from the "Test in Web Chat". Thus, I know what I want to send, and who I want to send it to. However, I do not know how to actually send it.
Currently, I have the following in my bot:
public class EchoBot : ActivityHandler
{
private ConcurrentDictionary<string, ConversationReference> _conversationReferences;
public EchoBot(ConcurrentDictionary<string, ConversationReference> conversationReferences)
{
_conversationReferences = conversationReferencs;
}
private void AddConversationReference(Activity activity)
{
var reference = activity.GetConversationReference();
_conversationReferences.AddOrUpdate(reference.User.Id, reference, (key, newValue) => reference);
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> context, CancellationToken cancellationToken)
{
AddConversationReference(context.Activity as Activity);
var parameters = GetParameters(); // Parses context.Activity.Text;
// Send a message to the target (i.e. someuser#mytenant.com)
var connection = new Microsoft.Bot.Connector.ConnectorClient(new Uri(context.Activity.ServiceUrl));
var tenant = context.Activity.GetChannelData<TeamsChannelData>().Tenant;
// how do I send the message to parameters.Target?
// Confirm message was sent to the sender
var confirmation = $"Message was sent to {parameters.Target}.";
await context.SendActivityAsync(MessageFactory.Text(confirmation));
}
}
I've reviewed how to send proactive notifications to users. However, I've been unsuccessful in a) getting the user specified in parameters.Target and b) sending a notification to that user. What am I missing?
First, you'll need to map user#email.com to their Teams userId (maybe with a static dictionary), which is in the format of:
29:1I9Is_Sx0O-Iy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzXXXXXXXXMij8BVMdBcL9L_RwWNJyAHFQb0TXXXXXX
You can get the Teams UserId by either:
Querying the roster, or
Having the user message the bot, and setting a breakpoint on an incoming message, looking at the Activity.ChannelData for the Teams userId, or
Dynamically build a static dictionary of all incoming messages that stores the user's email mapped to their Teams userId (I believe both are found in Activity.ChannelData).
Note: #1 and #2 both require a user to message the bot, first, which sort of defeats the purpose of proactive messages
After you have the appropriate Teams IDs, you just send a proactive message to a Teams user. The end of this link also mentions trustServiceUrl, which you may find handy if you run into permissions/auth issues when trying to send a proactive message.
I've been busy with a new application based on ionic. It's a new environment so I have a lot to explore.
I'd walked into some problems and search over the whole internet to find a solution and couldn't find one solving my problem. So I hope one of you guys know a solution.
I am trying to send notifications to my device using parse. That works fine, but now I want to send an uri attached with it, so that I can open a specific page clicking on the notification that has been recievied.
The problem is that I have no clue how to correctly send an attached uri and recieve that uri on the device to do something with it.
I hope some of you knows a solution.
I'm using ASP.NET to send the notification with a working initialized client.
var parsePush = new ParsePush();
// sending to all with your own data
parsePush.Data = new Dictionary<string, object>
{
{"alert", txtMessage.Text},// this is replacement for parsePush.Alert
{"sound", "notify.caf"},// for ios
{"badge", "Increment"}// for ios notification count increment on icon
//{"category", "http://google.nl" }
};
parsePush.SendAsync().Wait();
For the ionic side I don't have an event to recieve the notification and work with it. I just get the notification and get redirected to the home page of the app.
Please inform me if there are unclear details.
Thanks a lot!
I fixed this problem by searching over the whole internet.
The first thing I did was uncommenthing the category in my parsePush.data on the server side (see code in the question). In the category I define the uri. The next thing I did was adding "ParsePushPlugin.on" to my app.js. Those event are used when a notification is recieved or opened.
I added this code to my app.js inside the .run -> $ionicPlatform.ready.
ParsePushPlugin.getInstallationId(function (id) {
alert(id);
storage.set('parseId', id);
}, function (e) {
alert('error');
});
ParsePushPlugin.on('receivePN', function (pn) {
alert('yo i got this push notification:' + JSON.stringify(pn));
});
//customEvt can be any string of your choosing, i.e., chat, system, upvote, etc.
ParsePushPlugin.on('receivePN:chat', function (pn) {
alert('yo i can also use custom event to keep things like chat modularized');
});
ParsePushPlugin.on('openPN', function (pn) {
//you can do things like navigating to a different view here
//alert('Yo, I get this when the user clicks open a notification from the tray');
$state.go(pn.category)
});
As you can see "ParsePushPlugin.on('openPn')" has pn as parameters which contains all the data from the recieved and opened notification. This notification also contains the "category (uri)" which is passed from the server side.
I'm playing around with SignalR and was wandering how SignalR creates a connectionID is this based on my IP adress, the device I connect with or something else? And wether it is possible to set this ID manually. Let say I have a database with users which I give a unique number, can I use that number for the connectionID?
Kind regards
The SignalR connection Id is a generated guid. If you'd like to target users in a more meaningful way with your data, I found it useful to pass something with your client connection, such as a user Id and some other data from your database, along to the signalr hub and craft up a group based on what you provide. It should be a 1:1 mapping if you're trying to isolate users with your own identifiers.
you can do this by overriding OnConnected() in your hub, and implementing something like this, which would map the generated Id to your own. You can then target these groups (remember, 1:1, emulating an Id selector) to your liking.
public override Task OnConnected()
{
var user = new User()
{
Id = Context.QueryString["Id"]
Name = Context.QueryString["Name"]
}
Groups.Add(Context.ConnectionId, user.Id);
return base.OnConnected();
}
Mapping SignalR Users to Connections goes into more detail as well.
Using SignalR, I believe I should be able to send messages to specific connected users by using UserID Provider
Does anyone have an example of how this would be implemented? I've searched and searched and can not find any examples. I would need to target a javascript client.
The use case is, users to my site will have an account. They may be logged in from multiple devices / browsers. When some event happens, I will want to send them a message.
I have not looked into SignalR 2.0 but I think this is an extension of what the previous versions of SignalR used to have. When you connect to the hub you can decorate it with an Authorize attribute
[HubName("myhub")]
[Authorize]
public class MyHub1 : Hub
{
public override System.Threading.Tasks.Task OnConnected()
{
var identity = Thread.CurrentPrincipal.Identity;
var request = Context.Request;
Clients.Client(Context.ConnectionId).sayhello("Hello " + identity.Name);
return base.OnConnected();
}
}
As you can see you are able to access the Identity of the user accessing the Hub. I believe the new capability would be nothing more than an extension of this. Since the connection is always kept alive between the client and the hub you will always have the principal identity which will give you the UserId.
I believe this can help you: (linked from here)
A specific user, identified by userId.
Clients.User(userid).addContosoChatMessageToPage(name, message);
The userId can be determined using the IUserId interface:
public interface IUserIdProvider
{
string GetUserId(IRequest request);
}
The default implementation of IUserIdProvider is PrincipalUserIdProvider. To use this default implementation, first register it in GlobalHost when the application starts up:
var idProvider = new PrincipalUserIdProvider();
GlobalHost.DependencyResolver.Register (typeof(IUserIdProvider), () => idProvider);
The user name can then be determined by passing in the Request object from the client.