I am trying to do some stuff with the signalr.
My hub is
public class Customer : SignalR.Hubs.Hub
{
public void Send(string uid, string from, string msg)
{
string make = from + uid;
Clients.Addmsg(msg, make);
}
}
And Client side code is
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR-0.5.3.min.js" type="text/javascript"></script>
<script src="/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
$(function () {
// Proxy created on the fly
var care = $.connection.Customer;
$("#broadcast").click(function () {
// Call the chat method on the server
care.send($('#msg').val(), "HariOm", "jai jai ram")
.done(function () {
console.log('Success!');
})
.fail(function (e) {
console.warn(e);
});
});
// Declare a function on the chat hub so the server can invoke it
care.Addmsg = function (message, make) {
alert(message + msg);
};
// Start the connection
$.connection.hub.start();
});
</script>
I am getting this error after loading the page
Uncaught TypeError: Cannot set property 'Addmsg' of undefined
Your issue is that the name of the hub on the client-side should be lowercase, as the proxy generation generates the hub name in camel case. So your proxy should look like:
var care = $.connection.customer;
That is why you are getting the error that your care object is undefined. This is documented on the SignalR Wiki - JS Client Hubs page. Also if you look at the generated /signalr/hubs page in your browser, you will see the hub and its methods defined.
Related
I've created an UmbracoApiController named FormDatasourceController that resides in my plugin area to be used in ajax calls to get or post data.
[PluginController("AreaName")]
public class FormDatasourceController : UmbracoApiController
{
[HttpGet]
public IEnumerable<ICountry> GetAllCountries()
{
return MerchelloConfiguration.Current.MerchelloCountries().Countries;
}
}
and in the cshtml file I have this request
<script type="text/javascript">
$(function(){
$('#sbmtBtn').on("click", function () {
$.get('~/Umbraco/AreaName/FormDatasource/GetAllCountries', null)
.success(function (data) {
alert(data);
})
.fail(function (e) {
alert('failed' + e);
});
});
});
However, I always get error status 404. I tried to EnableCors but with no luck.
Any advise? I'm using umbraco 7
Edit:
For AngularJs controllers/resources in Umbraco, just do this:
change
$.get('~/Umbraco/AreaName/FormDatasource/GetAllCountries', null)
to
$.get('AreaName/FormDatasource/GetAllCountries', null)
That should get your call working. Ignore the ~/Umbraco/ bit.
Your API call should look:
~/Umbraco/AreaName/FormDatasource/GetAllCountries
See "Plugin based controller" at https://our.umbraco.org/documentation/Reference/Routing/WebApi/#plugin-based-controller.
Note, if you had inherited from 'UmbracoAuthorizedApiController' or 'UmbracoAuthorizedJsonController' your api call should be something like this:
~/Umbraco/backoffice/AreaName/FormDatasource/GetAllCountries
For more information, take a look at the bottom of this page in the documentation site under Backoffice Controllers:
https://our.umbraco.org/documentation/Reference/Routing/WebApi/
I have list of events in the database. Events have the following properties, Message, UserId, StartDate, EndDate, StartTime, EndTime.
My requirement is to alert the user by displaying the event before 15 minutes on the website. I am implementing this functionality by using SignalR concepts. This SignalR should process the condition in background and if it meets the condition (prior 15 minutes), it should be displayed to the respective user page automatically.
I have seen lot of SignalR examples on internet but all those examples are using a button click event or other events. In my case there is no button click events, SignalR should keep look into the database then notify Event if it meets the condition.
Please do needful
Here I am answering to my own question. It may helpful to others.
I have achieved this by using Timer class from using System.Threading namespace. Below is the working code for me.
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using SignalRNotifications.Models;
using System;
using System.Threading;
using System.Linq;
using WebMatrix.WebData;
namespace SignalRNotifications
{
[HubName("processEvents")]
public class ProcessEvents : Hub
{
UsersContext db = new UsersContext();
public void ShowEvent(string name)
{
Timer _timer = new Timer(dispmsg,
null,
TimeSpan.Zero,
TimeSpan.FromSeconds(2));
}
public void dispmsg(object state)
{
var userEvents = db.MyEvents.ToList().Where(f => f.StartDateTime.AddMinutes(-15) >= DateTime.Now).ToList();
Clients.All.BroadCastEvent("Hello Sridhar you have ("+userEvents.Count()+") Events<br/>");
}
}
}
Simply I wrote the code in Index.html for client
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div id="container"></div>
</body>
<script src="/Scripts/jquery-1.7.1.min.js"></script>
<script src="/Scripts/jquery.signalR-2.1.2.min.js"></script>
<script src="/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
var con = $.connection.processEvents;
con.client.broadCastEvent = function (name) {
$("#container").append(name);
}
$.connection.hub.start().done(function () {
con.server.showEvent("sridhar");
});
});
</script>
</html>
I'm trying to get Breeze.js talking to sharepoint. Does anyone know of any documentation on how to create a custom Breeze.js DataAdapter?
We are hoping to have some more guidance and documentation regarding connecting Breeze with Sharepoint endpoints within the next month or so. This work is currently in progress. So please stay tuned.
You can have breeze talk to sharepoint via oData. You need datajs to add oData support to breeze and note the call to breeze.config.initializeAdapterInstances({ dataService: "OData" });. See below.
<script src="scripts/jquery-1.8.3.min.js"></script>
<script src="scripts/knockout-2.3.0.js"></script>
<script src="scripts/q.js"></script>
<script src="scripts/datajs-1.1.1.min.js"></script>
<script src="scripts/breeze.debug.js"></script>
<script src="scripts/jquery-ui-1.9.1.custom.min.js"></script>
<script src="scripts/koGrid-2.1.1.js"></script>
<script type="text/javascript">
var my = {}; //my namespace
$(function () {
var serverAddress = "../_vti_bin/listdata.svc/";
breeze.config.initializeAdapterInstances({ dataService: "OData" });
var manager = new breeze.EntityManager(serverAddress);
my.vm = {
customers: ko.observableArray([]),
load: function () {
var query = breeze.EntityQuery.from("YourSPListHere").take(15);
manager.executeQuery(query, function (data) {
var results = data.results;
my.vm.customers(results);
});
}
}
my.vm.load();
ko.applyBindings(my.vm);
});
</script>
I have this action methid. It will return some JSON.
public JsonResult Get()
{
...
return new JsonResult { Data = data }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
Then I have in my view a script tag pointing to the Get action method.
<script type="text/javascript" src="#Url.Content("~/resource/get")"></script>
The problem is I can't access the JSON data in JS code. It seems like the JSON needs to be executed somehow. Any suggestion ?
You can just call the action in jQuery and then process the Json directly:
$.ajax({
dataType: "json",
url: "/resource/get",
success: function(data){
var obj = JSON.parse(data);
}
});
Or a shorter version:
$.getJSON('/resource/get', function(data) {
var obj = data;
});
If you want the JSON available ASAP, without an extra request, include it in the initial page load:
<script type="text/javascript">
var myJson = #Html.Action("Get");
</script>
Now you can just access the myJson variable in your script to access your data.
If you want it to be dumped into your HTML at the time the page is built on the server, you can add it to your view model, then render it directly on the page. Here's a pseudo-code example:
<script type="javascript">
var obj= JSON.parse('#Model.PropertyContainingJson');
</script>
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?
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.
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.
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");
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)
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.
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.