broadcast to all other session except the one which broadcasted - atmosphere

I am trying to use atmosphere, I want to broadcast msg for all the resources except for the one which broadcasted the msg, please advice how to exclude a resource.
In a page on click of a link I call code to broadcast msg and this same page has a public method with #Subscribe annotation ,this method gets called when msg is broadcasted. I want to broadcast msg to all other sessions except for current session which broadcasted , please advice.

Check the ExcludeSessionBroadcaster which comes with Atmosphere Runtime.

Related

How to get the client IP inside a Route

I'm trying to retrieve the customer's IP address during Iron Router's routing process. I have a server-side function for this (getIP), however the "waitOn" function inside the route won't wait for the server function to return:
waitOn: function () {
Meteor.call('getIP', function(error, clientIp){...}}
Can I force it to wait, or can I get the IP in any other way?
According to the documentation, the waitOn hook must return a Handler, a function or an array. the reason why it's not working for you, is that Meteor.call on the client is always async, and you have to define a callback function, which is called when the method responds.
Given that nature, you could only use the Meteor method, if the waitOn code supported a Promise, that could be resolved on the method callback.
The only way I see this is the following:
use a Meteor.onConnection hook, and store the current IP Address of the user in the user's profile (Meteor.users collection)
setup a global Subscription that publishes the entire user profile (since by default Meteor.user only publishes a few default document fields).
on the route waitOn, query the Meteor.user collection, and you will see the current detected IP Address of that user
I hope this helps and that it works for you.

Spring WebFlux Broken Stream Error Handling

I'm struggling to find any good examples on how to implement error handling with Spring WebFlux.
The use case I want to handle is notifying HTTP clients that a stream has terminated unexpectedly. What I have found it that with the out of the box behaviour, when a stream is terminated, for example by raising a RuntimeException after x items have been processed, is handled too gracefully! The client is flushed all items up until the exception is raised, and then the connection is closed. As far as the client is concerned the request was successful. The following code shows how this has been setup:
public Mono<ServerResponse> getItems(ServerRequest request) {
Counter counter = new Counter(0);
return ServerResponse
.ok()
.contentType(MediaType.APPLICATION_STREAM_JSON)
.body(operations.find(query, Document.class, "myCollection")
.map(it -> {
counter.increment();
if(counter.getCount() > 500) {
throw new RuntimeException("an error has occurred");
}
return it;
}), Document.class);
}
What is the recommended way to handle the error and notify the HTTP client that the stream terminated unexpectedly?
It really depends on how you'd like to communicate that failure to the client. Should the client display some specific error message? Should the client reconnect automatically?
If this is a "business error" that doesn't prevent you from writing to the stream, you could communicate that failure using a specific event type (look at the Server Sent Events spec).
Spring WebFlux supports ServerSentEvent<T>, which allows you to control various fields such as event, id, comment and data (the actual data). Using an Flux::onErrorMap operator, you could write a specific ServerSentEvent that has an "error" event type (look at the ServerSentEvent.builder() for more).
But this is not transparent to the client, as you'd have to subscribe to specific events and change your JavaScript code otherwise you may display error messages as regular messages.

How to get user sessionid , requested url to subscribe and user information during a websocket call using spring security

I am currently working on an application which is using websocket with stomp , sockjs, spring-mvc , spring-security.
The problem which I am facing is that ,after I have made a websocket call using stomp and sockjs from the UI (javascript part) I may not get the response at the same moment ,i.e, the response can be async .Now the backend code from spring mvc need to know the below three information for sending the data back to the UI to that particular user only who has requested for it
sessionid of the user who has actually requested for the resource
user whom to send the data
destination url.
The above 3 information will be needed for the below code to send the response from any class.
simpMessagingTemplate.convertAndSendToUser("username", </queue/destination-url>, dataToSend, sesionId of the requesting user for constructing the header);
I have already tried using the below methods:
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
RequestContextHolder.currentRequestAttributes().getSessionId()
but both of these gives NPE in the class were I need to send back the data.
So, I wanted to know if there is a way I can get these information using spring-security or if there is any other way to implement this.
Please let me know if you need any other information.
Thanks for your help in advance.
You could catch SessionConnectedEvent inside your event listener. I explained how to do it in this post
This is the excerpt from Spring Websocket documentation:
SessionConnectEvent — published when a new STOMP CONNECT is received indicating the start of a new client session. The event contains the message representing the connect including the session id, user information (if any), and any custom headers the client may have sent. This is useful for tracking client sessions. Components subscribed to this event can wrap the contained message using SimpMessageHeaderAccessor or StompMessageHeaderAccessor.
It looks like you will be able to extract all the information you need and store it somewhere.

Does SignalR send response to all the connections including the current connection, or all but excluding the current?

Let's say for example I've a button that displays alert to all the users. When I click the button, all the connected clients will see the alert.
And let's say this is done by calling a Server Method from client, which calls a function on Client that show an alert.
For example:
public class DemoHub : Hub {
public void ShowAlert(String message) {
Clients.All.showAlertMessage(message);
}
}
This is a server method in hub, that calls the client function to show alert message.
My question is, does the alert will be shown to the current client too? I mean, if I click the button, do I see the alert myself in this case?
Note: the above scenario is not a real scenario, that is just a similar illustration of my issue as my current scenario is rather complex to explain.
To broadcast to ALL connections including the caller you would use
Clients.All.showAlertMessage(message);
To broadcast to ALL EXCEPT the caller you will want to use the method
Clients.Others.showAlertMessage(message);
Can find more documentation on this at http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#callfromhub
This method above will broadcast to all connections except the current one which I believe is what you are looking for

ASP.NET Email Subscription

I have a database of email subscribers; approx. 1800 in the list. We have our own exchange server. I'm using the code below to grab each email address from the DB and send email, one at a time. I'm using an ASP.NET 4.0 Web Form to do this.
I notice the page hanging when the emails are being sent. What would be the best approach for implementing this - use a console app? How would I go about stress testing something like this?
I'm also getting an unhandled error message in the server log:
Event code: 3001
Event message: The request has been aborted.
// Call data access method via business class
TaxSalesBusiness bizClass = new TaxSalesBusiness();
DataSet ds = bizClass.GetSubscribers();
foreach (DataRow row in ds.Tables[0].Rows)
{
// Check well-formedness of each email adddress
if (!IsWellformedEmailAddr(row["Email"].ToString()))
{
// Ignore and log mal-formed email address
LogError(row["Email"].ToString()
+ " is a malformed email address. Message was not sent to this subscriber "
+ row["Name"].ToString() + ".", "");
continue;
}
else
{
string toAddress = row["Email"].ToString();
smtpClient.Send(fromAddress, toAddress, message.Subject, message.Body);
}
}
I notice the page hanging when the emails are being sent. What would
be the best approach for implementing this - use a console app?
Yes.
And you can SendAsync instead of waiting for one email to be sent before you send the next one. I don't know how much your Exchange server will like that, though.
The problem with your current approach is that sending 1800 emails one by one is going to take a lot of time and using a web page to perform such a long operation will probably timeout the request. You can perhaps do it on an async page and launch everything on its own thread, but that's just complicating things more than it needs to when you can perfectly do this in a Console App with far less lines of code and complications. Remember the KISS principle.
Another (more stable) solution could be to forward the mails to a (database?) queue, and have a Windows Service poll that queue once in a while. If there are new things on the queue the Windows Service is responsible for sending the e-mails.
This approach will help you steer clear from performance issues in your website, and it could make the delivery of the mails to be more reliable.

Resources