jueves, 1 de septiembre de 2011

SignalR with MVC3 | Chat App - Build asynchronous real-time persistant connection websites.

This post is based on Scott Hanselman's SignalR post - but tweaked for MVC3. Source.



This is getting my vote for Tool of The Year™ 2011.

As it's description states in their GitHub page:

Async signaling library for ASP.NET to help build real-time, multi-user interactive web applications.


In a nutshell SignalR lets you communicate with clients on your website in real time. Imagine Comet implementation without all the fuss. Dead easy to setup, dead easy to work with, fast as holy hell. Yes - I'm excited.

I'm going to show you how to build a small chat application using SignalR in an MVC3 application.



Create > New Project.



Create a new MVC3 project anywhere on your drive. This is the easy part.

Downloading and Installing SignalR.



Using NuGet you can either download SignalR using the package console, or by using the NuGet Package Manager UI. I'll show you the latter.

Right click on your References and select the manage option.

asd

Search for SignalR and add a reference to the SignalR library (the first one). NuGet will manage dependencies for you.

asdf

Setting up the Library.



Head on over to your _Layout.cshtml file and add the needed Javascript files. Remember: Using NuGet already packed up the javascript file neatly where they need to be.

[sourcecode language="csharp"]
<!-- Used for SignalR -->
<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.signalR.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/signalr/hubs")" type="text/javascript"></script>
[/sourcecode]


Next, head on over to the root of your solution and create a class called Chat.

asd

[sourcecode language="csharp"]
using SignalR.Hubs;

namespace SingalRTest
{
public class Chat : Hub
{
public void Send(string message)
{
//Call the addMessage method on all clients.
Clients.addMessage(message);
}
}
}[/sourcecode]

The Client Side Javascript



On the client side, we'll need to write some javascript to interact with your server side SignalR.

In your _layout.cshtml file, type in the following Javascript.

[sourcecode language="csharp"]
<script type="text/javascript">
$(function () {
// Proxy created on the fly
var chat = $.connection.chat;

// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) {
$('#messages').append('<li>' + message + '</li>');
};

$("#broadcast").click(function () {
// Call the chat method on the server
chat.send($('#msg').val());
});

// Start the connection
$.connection.hub.start();
});
</script>
[/sourcecode]

Your _layout.cshtml file should be looking like this right now:

[sourcecode language="csharp"]
<html >
<head runat="server">
<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.signalR.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/signalr/hubs")" type="text/javascript"></script>
</head>
<body>
<div>
<script type="text/javascript">
$(function () {
// Proxy created on the fly
var chat = $.connection.chat;

// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) {
$('#messages').append('<li>' + message + '</li>');
};

$("#broadcast").click(function () {
// Call the chat method on the server
chat.send($('#msg').val());
});

// Start the connection
$.connection.hub.start();
});
</script>
<input type="text" id="msg" />
<input type="button" id="broadcast" />
<ul id="messages"></ul>
</div>

<div>@RenderBody()</div>
</body>
</html>
[/sourcecode]

We're done now!



You can now type in a message, click the button to send it, and SignalR will broadcast this message out to any connected clients.

Is this fantastic or what?

What's going on behind the scenes? If you open up Firebug, you can see exactly what's going on:



Notice that the connection remains open, until we actually do something.

You can find the source for SignalR over on GitHub. Be sure to leave them feedback for any bugs you might find. This is a new project but a very promising one at that. Some very smart people are working on it.

Thanks for reading and stop polling your website for changes - use SignalR. :)

Related Reading:
Socket.IO - http://socket.io/
Nowjs - http://nowjs.com/

15 comentarios:

  1. Wow...this is actually Witchcraft...

    ResponderEliminar
  2. Cool... thanks. Worked for me.

    ResponderEliminar
  3. When I try to instal SignalR package in MVC3 project, I receive this error. Do you know a possible reason?
    Conflict occurred. 'jQuery 1.5.1' referenced but requested 'jQuery 1.6.3'. 'jQuery.vsdoc 1.5.1, jQuery.Validation 1.8.0, jQuery.UI.Combined 1.8.11' depend on 'jQuery 1.5.1'.

    ResponderEliminar
  4. I found a fix. I had to update JQuery libraries using VS2010 package updater. It added. Next, I will try to make this project work :)

    ResponderEliminar
  5. I'm glad you fixed your problem. Thanks for sharing the solution for other developers. :)

    ResponderEliminar
  6. Any luck getting it to work without the Hub ?

    ResponderEliminar
  7. To be honest I'm under a very tight schedule trying to get GoldRemates off the ground and running well. I haven't had that much time to tinker around with it, but I'm dying to!

    When you find something neat, please share your finds! :)

    ResponderEliminar
  8. WOW! This easily gets my vote for tool of the year too! How does this work??? This looks amazing.

    ResponderEliminar
  9. I am trying to implement SignalR in my existing MVC3 application to send alerts to all connected client. I am using Persistent connection. Just to test this i have placed a broadcast button on _Layout page. Clicking on broadcast button sends some text using connection.send($('#msg').val()); and is successfully received by the clients. But this only works when the message is broadcasted from first/default page when app loads. Once the page is redirected it looses the connection and on click of Croadcast button it throws error message "SignalR: Connection must be started before data can be sent. Call .start() before .send()". Please advice.

    ResponderEliminar
  10. Hi,
    Nice article - unfortunately it doesn't seem to work for me and I can't seem to figure out what I'm missing. Could you make the project available for download please? It's probably something silly that I'm missing.

    regards,
    Bill44077

    ResponderEliminar
  11. I simply wanted to thank you very much all over again. I am not sure the things that I might have followed without the actual concepts discussed by you regarding this area. Certainly was a real frightening difficulty in my position, nevertheless viewing this expert mode you processed it forced me to jump for delight. I'm just grateful for your assistance and even wish you know what a great job you are always doing training other individuals using a web site. I'm certain you have never come across all of us.

    ResponderEliminar
  12. Do you have something like Firebug installed? Run your MVC3 app and check in the Console tab to see if the connection is being made, or if an error if any is firing.

    ResponderEliminar
  13. Great post, exactly what I was looking for!

    ResponderEliminar
  14. Lol! Its amazing what Signalr brings to the game. I had one look, my jaw dropped and my mind was blown.

    ResponderEliminar
  15. Is there a problem with SignalR when using MVC4 internet template?

    ResponderEliminar