After looking at how to send messages from the server to the connected clients, let's swap sides and check how to perform the same operation, but in the opposite direction. We'll illustrate this scenario by building a simple JavaScript client that will send a message to the server as soon as the connection will be available.
This specific case is not really useful if taken alone, because any communication from client to server could be easily done by using plain old HTTP. However, when combined with the reception counterpart, it enables the construction of complex, real-time client-server workflows.
Before writing the code of this recipe, we need to create a new empty web application, which we'll call Recipe27
.
Let's first check how to build the server portion using the following steps:
EchoConnection
that is derived from PersistentConnection
, as we already did in the previous recipes of this chapter, and we will clean up the content generated by Visual Studio in order to have an empty class body, as follows:using Microsoft.AspNet.SignalR; namespace Recipe27 { public class EchoConnection : PersistentConnection { } }
Configuration()
method calling app.MapSignalR<EchoConnection>("/echo");
to map our Remove class derived from PersistentConnection
, as shown in the following code:using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(Recipe27.Startup))] namespace Recipe27 { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR<EchoConnection>("/echo"); } } }
EchoConnection
class, we can handle any incoming message in one place by simply overriding the OnReceived()
method exposed by PersistentConnection
as follows:protected override Task OnReceived(IRequest request,
string connectionId, string data)
{
...
}
This method will be called every time a client will use the available API method to send messages, and it will be supplied the following:
IRequest
that contains some context information related to the current HTTP requestIt's very basic and straightforward, but simple to use. One important detail we can appreciate here is the fact that the data payload is of type string
, while the counterpart server-side Send()
method we saw in the previous recipe was accepting any object
and taking care of its serialization on the wire. In the case of OnReceived()
, we stay at a lower level because the API does not offer any way to specify how the payload should be deserialized; therefore, the most sensible representation for the message is a string, which is the simplest way to represent the most common case of simple textual messages. This does not prevent us from sending more complex objects on the wire, but the deserialization task is not automatic, and we have to take care of it by ourselves.
OnReceived()
method with a simple call to send what we just received to any Trace listener available, and then by returning a null
value, as follows:System.Diagnostics.Trace.WriteLine( string.Format("Received: {0}", data)); return null;
Let's now build a corresponding client. As we always did through this chapter so far, we will use an HTML page called index.html
. As usual, we'll need to reference the JavaScript files we already used in the previous recipes first, and then we'll add a couple of lines of code to send a message to the server as soon as the connection will be available.
<script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script>
<script>
$(function () {
var c = $.connection('echo'),
c.start()
.done(function() {
c.send('hello'),
});
});
</script>
Through the $.connection
member, we first create a connection
object pointing to the /echo
endpoint, then we can call start()
on it to perform the actual connection, and eventually we use the done()
method to declare the function callback to be asynchronously invoked when the connection will be ready. Inside the callback, we can safely call the send()
method on the connection
object, passing on whatever value we want (in this case, a hello
string). SignalR will take care of building a proper representation of it, serializing it as a string, and using JSON if necessary. As we already said earlier, the payload will be received by the server as a plain string anyway, so this feature is clearly handy on the client side but has to be handled with care because it forces us to perform an explicit deserialization step on the server.
We are done. Let's open the index.html
page and check the Output window in Visual Studio to see the hello string printed out.