Accepting and Sending Messages in JavaScript with SignalR

In my last post, I showed how to use Microsoft’s new SignalR technology to create a server-side “hub” that would accept messages from clients and forward that message on to all connected clients. What’s special about SignalR is that, with a modern browser, those connected clients don’t have to send a request to the server to get their messages–the browsers will, receive their messages as soon as the hub sends the message (and the message will still get through with less up-to-date browsers though they will automatically fall back to older polling based methods).

In that last post I set up a hub (I called it MessageHub) with a method (called ReceiveMessage) that clients could call to pass a text string to the server–if you’ve forgotten what that hub looked like, I’ve repeated it at the end of this column with one tweak. My ReceiveMessage method called a function on the clients (named acceptMessage) to send that text string out to all connected clients. In this post, I’m going to show how to set up a JavaScript client to receive that message. I’ll also show how to send a message from your server-side hub back to all of the clients except the client that sent the message (it doesn’t make much sense to me to send the message to its originator).

Accepting Messages in JavaScript

The first step in creating a Web page that will accept messages from a server-side hub is to add the script libraries that the page will need. The order of these libraries matters so add them as shown below (I’ve put my libraries in a Scripts folder in my application but you can keep them anywhere you want in your project). While you must add a script tag for the last library (signalr/hubs) you won’t have that library in your project–it’s a proxy library that’s generated for your application by SignalR:

<script type="text/javascript" src="Scripts/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="Scripts/json2.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.signalR-1.0.0-rc2.min.js"></script>
<script type="text/javascript" src="/signalr/hubs"></script>

Now you’re ready to use some JavaScript to open a connection to your hub. Presumably, you’ll want to do this when the page first starts so, in the following code, I use the jQuery ready function (“$(function() {…”) to hold the code to make the connection. SignalR is implemented as a jQuery add-in so you use the jQuery identifier ($) to call the SignalR function called connection. You must also specify which of your application’s server-side hubs you’ll be connecting with by tacking on the name of your hub class to the connection function (the first letter of your hub class must be lowercased). So, to open a connection to my MessageHub class, I would use code like this:

<script type="text/javascript">
var conn;
$(function ()
  {
   conn = $.connection.messageHub;

The next step is to provide a function for the hub to call when the hub has a message to send to your client. When you created the hub, you specified the name of that function (I used AcceptMessage) and the number of parameters that would be passed (I used one parameter).  In the browser page, you add a property with the function name to the connection’s client property. Once that property is added, just set the property to the function you want to execute when the hub sends out a message using that function name.

This code defines a function with a single parameter (to match what my server-side code calls) and inserts the function into a property called AcceptMessage (to match the name I used in my server-side code–casing doesn’t seem to matter here). The function finds an element on the page with its id attribute set to messages and appends the text in the parameter passed from the server to that element:

 conn.client.AcceptMessage = function (message)
  {
    $('#messages').append('message');
  };

However, before the hub can send messages to your page (or you can send messages to the hub) you must start the connection by calling the start function on the hub property of the SignalR connection. This is an asynchronous process so you can’t be sure when it will complete–I’ll come back to that issue.

Sending Messages in JavaScript

You can also send messages to the server from JavaScript. In an ASP.NET application, I’d probably wire up a JavaScript function for sending messages to a Button object, using the Button’s OnClientClick property:

<asp:Button ID="sendMessageBtn" runat="server" Text="Connect" OnClientClick="return SendMessage();"/>

Again, to keep everything as simple as possible, all I’m going to do in my SendMessage function is call the method I created in my server-side hub (which I called ReceiveMessage). That method accepted a single parameter, a text string. To call your server-side method, you use the server property on the connection object, followed by the name of the method in your hub (again, with the first letter of the method name in lowercase). Calling my server-side RecieveMessage method and passing a single string parameter looks like this:

function SendMessage()
{
  conn.server.receiveMessage("Hello, World!");
  return false;
}

Before you can either accept or send messages, however, you must start the connection by calling it’s start function–which is an asynchronous operation. If  you’d prefer to wait until the start function successfully connects to the server-side hub before wiring up your Button’s click event you can use the done function on the start method to wait for the start method to complete.

This code not only starts the connection but also wires up my SendMessage function to the Button with its id attribute method set to sendMessageBtn when the start method completes:

$.connection.hub.start().done($('#sendMessageBtn').click(SendMessage));

With this change, I don’t need to use the OnClientClick property on my Button:

<asp:Button ID="sendMessageBtn" runat="server" Text="Connect"/>

Ignoring the Sender

To finish up this example: When returning the message, it doesn’t make much sense for the hub to send the message back to the client that originated it. In my server-side hub, I originally used this code to call a function called AcceptMessage on all the connected clients:

Me.Clients.All.AcceptMessage(Message)

However, I can use the AllExcept method to send messages to all clients except for those I specify in an array. I can specify a particular client by using that client’s ConnectionId. Fortunately, I can retrieve the ConnectionId of the client I’m currently processing from my hub’s Context property. So, to send a message back to all of my clients except the one who sent the message, I would rewrite my hub to look like this:

Imports System
Imports System.Web
Imports Microsoft.AspNet.SignalR

Public Class MessageHub
           Inherits Hub

  Public Sub ReceiveMessageOther(Message As String)
    Me.Clients.AllExcept(Me.Context.ConnectionId).AcceptMessage(Message)
  End Sub

End Class

However, SignalR provides a shortcut for doing this–just use the Others property on Clients to send a message to all the connected clients other than the calling client:

Me.Clients.Others.AcceptMessage(Message)

Of course, what I’ve created so far is just barely an application where the server calls the client when the server “knows” something that the client would like to know. Right now, only other JavaScript clients can add to the server’s store of information. In my next post, I’ll set up some  non-JavaScript clients (from both inside and outside the application) to provide information to the server that it can pass on to its JavaScript clients (and also have those non-JavaScript clients accept messages from the hub).

Peter Vogel

Type to search blog.learningtree.com

Do you mean "" ?

Sorry, no results were found for your query.

Please check your spelling and try your search again.

maltcasino maltcasino maltcasino bedava bahis güvenilir bahis siteleri canlı bahis siteleri
bedava bahis Yatırımsız Deneme Bonusu bonus veren siteler