Reputation: 438
I'm trying to use SignalR with MVC bundle, but having problem finding out how to include the /signalr/hubs script into the bundle. For now I have to insert the path in between jquery.signalR and my code. That will result in three javascript file requests.
Is there any way to include /signalr/hubs into my mvc bundle?
Upvotes: 25
Views: 10497
Reputation: 41008
You can generate the code with the Microsoft.AspNet.SignalR.Utils
NuGet package. Add that to your project, then you can add the below as a post-build script (Project -> {project name} Properties -> Build Events). It should be a post-build script and not pre- since you want it to build against your updated hub code after it's compiled.
It will find whatever version of the Microsoft.AspNet.SignalR.Utils
package that you have installed and put the server.js file in the Scripts folder.
You must also have a version redirect for Newtonsoft.Json
in your web.config file (assuming your project uses Newtonsoft.Json
). This is because signalr.exe is built against version 6.0.0 and you're likely using a newer version. The /configFile
switch is to tell it to use your project's config file so that it uses the redirect.
Post-build script:
cd $(ProjectDir)\Scripts
FOR /F "usebackq delims=" %%p IN (`dir ..\..\packages /b /ad ^| find "Microsoft.AspNet.SignalR.Utils"`) DO (
set "UTILSPATH=%%p"
)
$(SolutionDir)\packages\%UTILSPATH%\tools\net40\signalr.exe ghp /path:$(TargetDir) /configFile:$(TargetPath).config
Then include ~/Scripts/server.js
in your bundle.
Upvotes: 1
Reputation: 613
I used @KTW response mentioned on this Thread and here is the complete change
BundleConfig
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/modernizr-2.6.2.js",
"~/Scripts/jquery-2.2.3.js",
"~/Scripts/jquery-ui-1.11.4.js",
"~/Scripts/jquery.multiselect.js",
"~/Scripts/jquery.dataTables.js",
"~/Scripts/jquery.jstepper.min.js",
"~/Scripts/underscore.min.js"
));
bundles.Add(new ScriptBundle("~/bundles/SignalRScripts").Include(
"~/Scripts/jquery.signalR-2.2.2.min.js",
"~/Scripts/signalRBundle.js",
"~/Scripts/Views/Search/SignalRFunctions.js"));
}
}
SignalRFunctions.js
$(function() {
// Declare a proxy to reference the hub.
var usersHub = $.connection.currentUsersHub;
//Create a function that the hub can call to broadcast messages.
usersHub.client.broadcastMessage = function(reservationNumber, usrName) {
//Message broadcast from server
//now find the id with reservationNumber on the page and to that append the user name
var id = '#' + reservationNumber;
if ($(id).length) {
if (usrName.length) {
itemsOpened($(id), usrName);
} else {
itemsClosed($(id));
}
}
//else {
// //is it possible that server broad casted for a reservationNumber and is not available at the client?
//}
};
//Accepts dictionary from hub and goes through search results
//https://stackoverflow.com/questions/7776337/reading-c-sharp-dictionary-in-javascript
usersHub.client.broadcastCollection = function (reservationNumberAndUsers) {
for (var resNumKey in reservationNumberAndUsers) {
if (reservationNumberAndUsers.hasOwnProperty(resNumKey)) {
//Message broadcast from server
//now find the id with ReservationNumber on the page and to that append the user name
var id = '#' + resNumKey;
if ($(id).length) {
if (reservationNumberAndUsers[resNumKey].length) {
itemsOpened($(id), reservationNumberAndUsers[resNumKey]);
} else {
itemsClosed($(id));
}
}
}
}
};
$.connection.hub.start().done(function() {
var searchedReservationNumbers = [];
if (typeof jsData !== 'undefined') {
if (jsData && jsData.length) {
for (var i = 0; i < jsData.length; i++) {
searchedReservationNumbers.push(jsData[i].UReservationNumber);
}
if (searcheduReservationNumbers.length !== 0) {
usersHub.server.getWorkingUsersOnUReservationNumber(searcheduReservationNumbers);
}
}
}
}).fail(function () { console.log('Could not Connect To SignalrHub!'); });
/*In case we would decide to continuously reconnect making connection to server.
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
},
5000); // Restart connection after 5 seconds.
});*/
function itemsOpened(elem, id) {
var item = "Opened By - " + id;
elem.prop('title', item);
elem.css('background-color', 'chocolate');
};
function itemsClosed(elem) {
elem.prop('title', "");
elem.css('background-color', '');
};
});
signalRBundle.js
(function ($) {
$.ajax({
url: "/signalr/hubs",
dataType: "script",
async: false
});
}(jQuery));
/* Source https://stackoverflow.com/questions/11556110/signalr-and-mvc-bundle */
SomePartialView.cshtml Instead of writing below in above partial view
@using Localization
@using Newtonsoft.Json
@model NameSpace.ViewModels.FilterVM
@{
ViewBag.Title = Strings.Filter;
}
@using (Html.BeginForm())
{
<div class="large-12 columns">
---SOME CODE HERE
</div>
}
@section scripts
{
<script type="text/javascript" language="javascript">
var jsData = @Html.Raw(JsonConvert.SerializeObject(Model));
</script>
<script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>
<script src="~/signalr/hubs"></script>
<script src="~/Scripts/Views/Search/SignalRFunctions.js"></script>
}
This changed to
@using Localization
@using Newtonsoft.Json
@model NameSpace.ViewModels.FilterVM
@{
ViewBag.Title = Strings.Filter;
}
@using (Html.BeginForm())
{
<div class="large-12 columns">
---SOME CODE HERE
</div>
}
@section scripts
{
<script type="text/javascript" language="javascript">
var jsData = @Html.Raw(JsonConvert.SerializeObject(Model));
</script>
@Scripts.Render("~/bundles/SignalRScripts")
}
Notice
@Scripts.Render("~/bundles/SignalRScripts")
in partial view above.Without @KTW file above(ajax request to /signalr/hubs)
var usersHub = $.connection.currentUsersHub;
was always coming as null.
Upvotes: 0
Reputation: 20400
From asp.net, using the SignalR.Utils NuGet package, I found that I needed to be in the directory with the DLL that has the hub in it:
(assuming you have a standard solution structure and are using 2.2.0 of SignalR.Utils)
cd C:\YourSolution\YourProjectWithTheHub\bin\Debug
..\..\..\packages\Microsoft.AspNet.SignalR.Utils.2.2.0\tools\signalr.exe ghp
After running the tool, there will be a server.js
file in the directory you ran it from (in this case, Debug
).
(Note: I couldn't get it to work when specifying the path with the /p flag, and for some reason even when it does work, it creates a temp directory with the signalr.exe file in it)
Upvotes: 1
Reputation: 950
I know this is an old thread but I would like to add the following for SignalR 2.x. I really wanted to bundle the proxy using SquishIt and by trial and error I managed to come up with the following:
using Microsoft.AspNet.SignalR
using Microsoft.AspNet.SignalR.Hubs
var resolver = new DefaultHubManager(new DefaultDependencyResolver());
var proxy = new DefaultJavaScriptProxyGenerator(resolver, new NullJavaScriptMinifier());
string iCanHazScriptNao = proxy.GenerateProxy("/signalr");
Upvotes: 2
Reputation: 719
A bit late, but here is my contribution:
Create a javascript file with the following contents:
(function ($) {
$.ajax({
url: "/signalr/hubs",
dataType: "script",
async: false
});
}(jQuery));
Then add the file to the bundles collection.
This will load the "/signalr/hubs" code for you.
Upvotes: 49
Reputation: 2517
The default /signalr/hubs script is generated dynamically by the runtime on the first request and then cached.
You can use hubify.exe (see http://weblogs.asp.net/davidfowler/archive/2012/06/10/signalr-0-5-1-released.aspx for details) to pre-generate the file yourself, so you can add it into the MVC bundle.
Upvotes: 14