WebSocketServlet: Send message to particular connection - html

I am trying implement a Websocket connection taking an example from here - https://gist.github.com/chitan/3063774.
This is a echo server.
My question is -
How can i take a message from a particular user and send it to another user instead of echoing to the same user.
I have searched a lot and most of the examples i have found are Echo examples.

In Java EE7, you can do that easily. Think about an simple example. If you write client.getBasicRemote().sendObject(message); in a method with #OnMessage annotation than it will be available only active client session.
#ServerEndpoint("/websocket")
public class ChatEndpoint {
#OnMessage
public void message(String message, Session client) throws IOException, EncodeException {
client.getBasicRemote().sendObject(message);
}
}
if you loop the message on client.getOpenSessions() then it will be available to all clients:
#OnMessage
public void message(String message, Session client) throws IOException, EncodeException {
for (Session peer : client.getOpenSessions()) {
peer.getBasicRemote().sendObject(message);
}
}
For details, go to this tutorial.

If you still need to use Java 6 and WebSocketServlet you can do something like this:
public class WsChatServlet extends WebSocketServlet{
public StreamInbound createWebSocketInbound(String protocol){
MyMessageInbound ms = new MyMessageInbound();
// store ms somewhere and than find it and use getWsOutbound() to respond
return ms;
}
...
}

Related

How to show custom error page in ServiceStack

I have read through Error Handling, ServiceStack_Succinctly.pdf, ServiceStack 4 Cookbook and various SO questions and am still unable to get the following working.
I want a way to show my own "pretty" error page for any exception that is thrown in any of my services. If any exception is thrown I want to take the user to a friendly page that shows the error message without any information that "mere mortals" won't understand.
Ideally I want this while maintaining typed responses on my service requests, i.e. not
public object Get(GetOrder request)
{
return new GetOrderResponse()
{
...
}
}
but rather
public GetOrderResponse Get(GetOrder request)
{
return new GetOrderResponse()
{
...
}
}
I'd appreciate guidance on how to get this working or an example where this is done.
Thanks.
Have a look at the options for Fallback Error Pages e.g. you can display an /oops.cshtml Razor page with:
public override void Configure(Container container)
{
Plugins.Add(new RazorFormat()); //Register ServiceStack.Razor Plugin
this.GlobalHtmlErrorHttpHandler = new RazorHandler("/oops"),
}
Or for more fine-grained control, use IAppHost.CustomHttpHandlers for specifying custom HttpHandlers to use with specific error status codes, e.g.:
public override void Configure(Container container)
{
this.CustomHttpHandlers[HttpStatusCode.NotFound] =
new RazorHandler("/notfound");
this.CustomHttpHandlers[HttpStatusCode.Unauthorized] =
new RazorHandler("/login");
}

How can I manually handle any subscribed to message type in NServiceBus?

I'm trying to build a layer over NServiceBus to make it simpler for other developers to use.
I'm trying to do without the config file and managed to get the publisher to work:
public class NServiceBusPublisher
{
private IBus _Bus { get; set; }
public void NServiceBusPublisher(string argInputQueue, string argErrorQueue)
{
Configure configure = NServiceBus.Configure.With().DefaultBuilder();
var transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
transport.ConfigureProperty(t => t.InputQueue, argInputQueue);
transport.ConfigureProperty(t => t.ErrorQueue, argErrorQueue);
transport.ConfigureProperty(t => t.NumberOfWorkerThreads, 1);
transport.ConfigureProperty(t => t.MaxRetries, 5);
_Bus =
configure
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start();
}
public void Publish(NServiceBus.IMessage argMessage)
{
_Bus.Publish(argMessage);
}
}
I also want to have an NServiceBus Subscriber and make it possible for developers to subscribe to any number of message types as long as the message inherits from NServiceBus.IMessage:
public class NServiceBusSubscriber
{
private IBus _Bus { get; set; }
public void NServiceBusSubscriber(string argInputQueue, string argOutputQueue, string argErrorQueue, string messagesAssembly)
{
Configure configure = NServiceBus.Configure.With().DefaultBuilder();
var transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
transport.ConfigureProperty(t => t.InputQueue, argInputQueue);
transport.ConfigureProperty(t => t.ErrorQueue, argErrorQueue);
transport.ConfigureProperty(t => t.NumberOfWorkerThreads, 1);
transport.ConfigureProperty(t => t.MaxRetries, 5);
var ucb = configure.Configurer.ConfigureComponent<NServiceBus.Unicast.UnicastBus>(ComponentCallModelEnum.Singleton);
ucb.ConfigureProperty(u => u.MessageOwners, new Dictionary<string,string>()
{
{messagesAssembly, argOutputQueue}
});
_Bus =
configure
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.ImpersonateSender(false)
.DoNotAutoSubscribe()
.CreateBus()
.Start();
}
public void Subscribe<T>() where T : NServiceBus.IMessage
{
_Bus.Subscribe<T>();
}
}
The problem is that I couldn't find any way to attach an event handler to a particular message type.
Could you please help me figure this out?
Its been a while since the question has been asked, so I am not sure if the problem has been solved, but here's one way you can do it using Bus.Subscribe (although as has been said by other respondents this is not the prescribed way of doing it NServiceBus)
Subscribe the to the message type using the subscribe overload
void Subscribe(Type messageType, Predicate<IMessage> condition);
Then you can handle the message in the delegate
private bool Handle(NServiceBus.IMessage nsbMsg)
{
//you get the message instance that you can handle
//return true
}
So, your code would then be
class MySubscriber
{
public IBus Bus {get; set;}
public void Subscribe()
{
Bus.Subscribe(typeof(MyMessage), Handle);
}
public void Handle(NServiceBus.IMessage nsbMsg)
{
var msg = nsbMsg as MyMessage;
//your code
return true;
}
}
However please note that by doing this you have to manage the lifetime of the handler yourself, which otherwise would have been managed for you by NServiceBus using the IOC framework of your choice.
You will also have to pass the reference to IBus explicitly which would be injected for you automatically if you were just implementing the IHandleMessage interface.
An architectural point here is that NSB is a full fledged 'ESB', its not just a messaging layer. Adding another layer over your ESB is IMHO an abstraction too many.
I think you are missing the concept behind NServiceBus.
Based on the code you show I get the impression that you envision services that publish messages and others that process those messages. In my experience most processes do both: they subscribe to events or process incoming commands and in result publish new events and send new commands.
In your setup you would need to have publisher and subscriber instances for each of these message types.
NServiceBus is built for the situation I describe. You configure and start 1 bus instance and that orchestrates the complete application.
If you want to make it easier for developers to use NServiceBus I would concentrate on the configuration part only. In our company I have created a ServicebusConfigurator class that configures NServiceBus according our company standards and extracted that in a framework and a simple extension method for the .NET Core generic host. The only code our developers need to write to create a Windows Service that hosts an NServiceBus endpoint is something like this:
internal static class Program
{
private static int Main(string[] args)
{
return (int)Host.CreateDefaultBuilder(args) //.NET Core generic host
.WithNServiceBus() //configure NServiceBus according to our standards and start it.
.UseTopshelf<Worker>() // use Worker as the actual service doing the work.
.EnableNsbInstallersDuringInstall() // Execute any NServiceBus transport specific installation code during install of the service.
.Run(); // Run the thing.
}
}
Since you are not auto-subscribing the first thing you will need to do is subscribe to the message type via Bus.Subscribe(). Others could do this at the IWantToRunAtStartUp extension point(implement the interface in a class somewhere). From there, each subscriber will implement the IHandleMessages<T> interface. Implementing this interface wires you to a message where "T" is the message type.
When NSB starts up it will scan the local bin dir and find all your interface implementations and wire them up on your behalf internally. From there it will dispatch to the correct handler when a message of that type arrives.
NServiceBus automatically handles the subscription of messages. When you invoke Configure.With()....Start(); NServiceBus will scan to determine which assemblies implement IHandleMessages(SomeMessage) and it will send a subscription request to the publisher.
When you add "DoNotAutoSubscribe", you've got to manually get all messages being handled and do a Bus.Subscribe() for each of them.
Beyond that, NServiceBus will automatically handle the routing of an incoming message to the appropriate handler. In your subscriber code above, are you receiving an error message or are the messages disappearing from the queue?

Exception/MessageBox in Calibur.Micro

I start learning Caliburn.Micro and I am little confuse of handling with exception/messange box in view model class.
I found some blogs about, for example:
http://frankmao.com/2010/11/18/handling-messagebox-in-caliburn-micro/
For example some method in view model class which can produce exception.
public void MethodWichCanProduceEx(string arg1, string arg2 )
{
if(arg1==null)
throw new ArgumentNullException("arg1 is null");
if (arg2 == null)
throw new ArgumentNullException("arg2 is null");
try
{
}
catch (Exception exception)
{
throw exception;
//? show message box MessageBox.Shox(exception.Message)
}
}
What is correct handling and showing these exception in view ? It exist any kind of pattern for caliburn.micro?
It possible trace exception as in .NET in text, xml file ?
For example I would like trace exception in xml, text file and in view show only message.box or something message.
Thank for advance, maybe is my question little stupid, sorry I am only learning calibur.micro.
You'll want to always work against abstractions in your view models, in the case of message boxes, you don't want to have to wait for user input when you come to unit test your view models.
The Frank Mao code you linked to uses a delegate to abstract the implementation of the message box from the view model, but I would use an interface here. You can think of a delegate as an interface with a single method, but the advantage of using an interface in this context is that you can have different methods depending on the type of message you wish to show. For example, you could have a ShowMessageError, ShowMessageWarning, ShowMessageInfo etc.
So, define a contract for your message box:
public interface IMessageBox
{
void ShowException(Exception exc);
}
Inject the message box dependency into your view model, e.g. via the constructor
public class MyViewModel
{
private readonly IMessageBox messageBox;
public MyViewModel(IMessageBox messageBox)
{
this.messageBox = messageBox;
}
public void MethodThatCanThrowException()
{
try {}
catch(Exception exc)
{
// log the exception here
...
// show message box
this.messageBox.ShowException(exc);
}
}
}
You can then implement the message box anyway you wish, either using the windows system message box, or nicer still use your own view/viewmodel to display the message, perhaps using the Caliburn.Micro WindowManager.ShowDialog().
An implementation that uses the windows system message box may look like:
public class StandardMessageBox : IMessageBox
{
public void ShowException(Exception exception)
{
MessageBox.Show(exception.ToString(), "Error Occurred");
}
}
In production code, you can register StandardMessageBox against the IMessageBox interface in your IoC container.
In unit test land, you can mock out IMessageBox and have it do nothing, or in the case of methods with a result from the message box, always return a value you wish.
For logging the exception, I would look at a logging framework such as log4net (http://logging.apache.org/log4net/index.html) or NLog (http://nlog-project.org/)

Exception handling with WCF Data Services

I want to customize exceptions/errors thrown from my WCF Data Service, so clients get as much as possible information about what exactly went wrong/what is missing. Any thoughts on how this could be achieved?
There are a few things you need to do to ensure exceptions bubble over HTTP pipe to the client .
You must attribute your DataService class with the following:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class MyDataService : DataService
You must enable verbose errors in the configuration:
public static void InitializeService(DataServiceConfiguration config)
{
config.UseVerboseErrors = true;
}
It is best to throw DataServiceException within. The WCF Data Service runtime knows how to map the properties to the HTTP response and will always wrap it in a TargetInvocationException.
[WebGet]
public Entity OperationName(string id)
{
try
{
//validate param
Guid entityId;
if (!Guid.TryParse(id, out entityId))
throw new ArgumentException("Unable to parse to type Guid", "id");
//operation code
}
catch (ArgumentException ex)
{
throw new DataServiceException(400, "Code", ex.Message, string.Empty, ex);
}
}
You can then unpack this for the client consumer by overriding the HandleException in your DataService like so:
/// <summary>
/// Unpack exceptions to the consumer
/// </summary>
/// <param name="args"></param>
protected override void HandleException(HandleExceptionArgs args)
{
if ((args.Exception is TargetInvocationException) && args.Exception.InnerException != null)
{
if (args.Exception.InnerException is DataServiceException)
args.Exception = args.Exception.InnerException as DataServiceException;
else
args.Exception = new DataServiceException(400, args.Exception.InnerException.Message);
}
}
See here for more info...
You can decorate your service class with this attribute ServiceBehaviorAttribute like so :
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class PricingDataService : DataService<ObjectContext>, IDisposable
{
...
}
You need to create custom exceptions for this.
Please read this post here: Why Create Custom Exceptions?
Which language are you developing in?
If you need further guidance, please add some comments.
I don't think he wants to know how to throw / catch exceptions in .NET.
He probably want to get thoughts on how to tell the clients consuming a WCF Data Service that something (and what) went wrong when an exception is being thrown / caught at the server(service) side.
WCF Data Services uses HTTP request / response messages and you can't just throw an exception from the service to the client.

GWT JsonpRequestBuilder Timeout issue

I am getting time out from using JsonpRequestBuilder.
The entry point code goes like this:
// private static final String SERVER_URL = "http://localhost:8094/data/view/";
private static final String SERVER_URL = "http://www.google.com/calendar/feeds/developer-calendar#google.com/public/full?alt=json-in-script&callback=insertAgenda&orderby=starttime&max-results=15&singleevents=true&sortorder=ascending&futureevents=true";
private static final String SERVER_ERROR = "An error occurred while "
+ "attempting to contact the server. Please check your network "
+ "connection and try again.";
/**
* This is the entry point method.
*/
public void onModuleLoad() {
JsonpRequestBuilder requestBuilder = new JsonpRequestBuilder();
// requestBuilder.setTimeout(10000);
requestBuilder.requestObject(SERVER_URL, new Jazz10RequestCallback());
}
class Jazz10RequestCallback implements AsyncCallback<Article> {
#Override
public void onFailure(Throwable caught) {
Window.alert("Failed to send the message: " + caught.getMessage());
}
#Override
public void onSuccess(Article result) {
// TODO Auto-generated method stub
Window.alert(result.toString());
}
The article class is simply:
import com.google.gwt.core.client.JavaScriptObject;
public class Article extends JavaScriptObject {
protected Article() {};
}
The gwt page, however, always hit the onFailure() callback and show this alert:
Failed to send the message. Timeout while calling <url>.
Fail to see anything on the Eclipse plugin console. I tried the url and it works perfectly.
Would appreciate any tip on debugging technique or suggestion
Maybe you should set the callback function explicitly via setCallbackParam, since you have callback=insertAgenda in your url - I presume that informs the server what should be the name of the callback function that wraps the JSON.
Also, it's worth checking Firebug's console (or a similar tool for your browser) - even if GWT doesn't report any exceptions, Firebug still might.
PS: It's useful to use a tool like Firebug to see if the application does in fact receive the response from the server (that would mean that, for example, you do need the setCallbackParam call) or maybe there's something wrong on the server side (for whatever reason).
You have to read the callback request-Parameter (default callback, value something like __gwt_jsonp__.P0.onSuccess) on serversite and have to modify the output to
<callback>(<json>);
In this case:
__gwt_jsonp__.P0.onSuccess(<json>);
Both of these guys are absolutely correct, but here is a concrete example to help you understand exactly what they are referring too.
This is a public JSON api. Take a look at the results:
http://ws.geonames.org/postalCodeLookupJSON?postalcode=M1&country=GB&maxRows=4
This public API supports JSONP through the predefined parameter 'callback'. Basically whatever value you pass into callback, will be used as the function name to wrap around the JSON data you desire. Take a look at the results of these few requests:
http://ws.geonames.org/postalCodeLookupJSON?postalcode=M1&country=GB&maxRows=4&callback=totallyMadeUp
http://ws.geonames.org/postalCodeLookupJSON?postalcode=M1&country=GB&maxRows=4&callback=trollingWithJSONP
It could be happening because of another reason, that the webservice call is returning a JSON object and but the callback is expecting JSONP object (note there is a difference).
So if you are dealing with google maps api, and you are seeing this exception, you need to change it to api provide by maps api, something like
final GeocoderRequest request = GeocoderRequest.create();
request.setAddress(query);
try {
GWT.log("sending GeoCoderRequest");
if (m_geocoder == null) {
m_geocoder = Geocoder.create();
}
m_geocoder.geocode(request, new Geocoder.Callback() {
#Override
public void handle(final JsArray<GeocoderResult> results,
final GeocoderStatus status) {
handleSuccess(results, status);
}
});
} catch (final Exception ex) {
GWT.log("GeoCoder", ex);
}
Or else you could use RequestBuilder as in gwt library.