I had lot of difficulties after upgrading signalR & .NET version.
Previously I had 1.XX version now I have 2.4.0 signal R version.
This question is directly connected with - https://github.com/SignalR/SignalR/issues/4339
But after upgrade signal R doesn't work.
Now the problem is client-side functions cannot call.
I just tried this: Signalr doesn't call client side functions
and fixed it according to the correct answer:
In your init prior to $.connection.hub.start call your _subscribe method.
Later I went through a bit deeper down on this issue, and added console.log below place in my signalr.js
connection.socket.onmessage = function (event) {
var data;
try {
console.log(event.data);
data = connection._parseResponse(event.data);
}
catch (error) {
transportLogic.handleParseFailure(connection, event.data, error, onFailed, event);
console.log("socket error" + event.data);
return;
}
if (data) {
transportLogic.processMessages(connection, data, onSuccess);
}
};
After every one joins meeting -> meeting start and ask for vote (this place we should call signalR)
From vote asking person side I see console log like this:
Normal user ( voting persons console log looks like this:
This is from Firefox - another user:
I think it already triggering - client hub event 'sendOnlineMeetingVoteRequest' on hub 'NotificationHub'.
It already hit server-side function too but the thing is it never hits this part of the code:
notificationHub.client.sendOnlineMeetingVoteRequest = function (token, meetingId, meetingVoteId) {
debugger;
if (token == '#Model.Organization' && '#Model.MeetingId' == meetingId) {
ShowMeetingOnlineMeetingVotePopup(meetingId, meetingVoteId);
}
};
I went through http://localhost:33852/signalr/hubs
/*!
* ASP.NET SignalR JavaScript Library v2.3.0-rtm
* http://signalr.net/
*
* Copyright (c) .NET Foundation. All rights reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*
*/
/// <reference path="..\..\SignalR.Client.JS\Scripts\jquery-1.6.4.js" />
/// <reference path="jquery.signalR.js" />
(function ($, window, undefined) {
/// <param name="$" type="jQuery" />
"use strict";
if (typeof ($.signalR) !== "function") {
throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/js.");
}
var signalR = $.signalR;
function makeProxyCallback(hub, callback) {
return function () {
// Call the client hub method
callback.apply(hub, $.makeArray(arguments));
};
}
function registerHubProxies(instance, shouldSubscribe) {
var key, hub, memberKey, memberValue, subscriptionMethod;
for (key in instance) {
if (instance.hasOwnProperty(key)) {
hub = instance[key];
if (!(hub.hubName)) {
// Not a client hub
continue;
}
if (shouldSubscribe) {
// We want to subscribe to the hub events
subscriptionMethod = hub.on;
} else {
// We want to unsubscribe from the hub events
subscriptionMethod = hub.off;
}
// Loop through all members on the hub and find client hub functions to subscribe/unsubscribe
for (memberKey in hub.client) {
if (hub.client.hasOwnProperty(memberKey)) {
memberValue = hub.client[memberKey];
if (!$.isFunction(memberValue)) {
// Not a client hub function
continue;
}
// Use the actual user-provided callback as the "identity" value for the registration.
subscriptionMethod.call(hub, memberKey, makeProxyCallback(hub, memberValue), memberValue);
}
}
}
}
}
$.hubConnection.prototype.createHubProxies = function () {
var proxies = {};
this.starting(function () {
// Register the hub proxies as subscribed
// (instance, shouldSubscribe)
registerHubProxies(proxies, true);
this._registerSubscribedHubs();
}).disconnected(function () {
// Unsubscribe all hub proxies when we "disconnect". This is to ensure that we do not re-add functional call backs.
// (instance, shouldSubscribe)
registerHubProxies(proxies, false);
});
proxies['NotificationHub'] = this.createHubProxy('NotificationHub');
proxies['NotificationHub'].client = { };
proxies['NotificationHub'].server = {
sendMeetingStartMessage: function (token, meetingId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendMeetingStartMessage"], $.makeArray(arguments)));
},
sendMeetingStopMessage: function (token, meetingId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendMeetingStopMessage"], $.makeArray(arguments)));
},
sendMeetingTreeRefreshRequest: function (token, meetingId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendMeetingTreeRefreshRequest"], $.makeArray(arguments)));
},
sendMessage: function (token, meetingId, agendaGroupItemId, motionId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendMessage"], $.makeArray(arguments)));
},
sendOnlineMeetingVoteCloseRequest: function (token, meetingId, meetingVoteId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendOnlineMeetingVoteCloseRequest"], $.makeArray(arguments)));
},
sendOnlineMeetingVoteRequest: function (token, meetingId, meetingVoteId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendOnlineMeetingVoteRequest"], $.makeArray(arguments)));
},
sendOnlineVoteCloseRequest: function (token, meetingId, agendaGroupItemId, motionId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendOnlineVoteCloseRequest"], $.makeArray(arguments)));
},
sendOnlineVoteRequest: function (token, meetingId, agendaGroupItemId, motionId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendOnlineVoteRequest"], $.makeArray(arguments)));
},
sendOnlineVoteResult: function (token, meetingId, agendaGroupItemId, motionId, selectedVotingOptionId) {
return proxies['NotificationHub'].invoke.apply(proxies['NotificationHub'], $.merge(["sendOnlineVoteResult"], $.makeArray(arguments)));
}
};
return proxies;
};
signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
$.extend(signalR, signalR.hub.createHubProxies());
}(window.jQuery, window));
So I didn't found any error on it too.
Still, I cannot figure it out why this is happening but I went through the sample project that uses signalR 2.0.3.0 version
I went to reference & just noted that this reference - Microsoft.AspNet.SignalR.Owin is not included in that sample project that I downloaded.
I did some investigation furthermore & find out this:
'The call is ambiguous between the following methods or properties'
This error will occur if a reference to Microsoft.AspNet.SignalR.Owin
is not removed. This package is deprecated; the reference must be
removed and the 1.x version of the SelfHost package must be
uninstalled.
(https://learn.microsoft.com/en-us/aspnet/signalr/overview/releases/upgrading-signalr-1x-projects-to-20)
Do I need to remove that?
In my web config, there is no code like this.
I just call this function purely from another place - about us page. only add relevant script and function.
from that place, it worked.
after that, I changed some scripts placing and fix this issue.
the main thing is I didn't get any error or anything. thing looks working all the time. but because of some script placement, it doesn't work.
Related
for example in my index.html I have a code to detect an update for service worker and the code is like this:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(reg => {
reg.addEventListener('updatefound', () => {
// A wild service worker has appeared in reg.installing!
newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
// Has network.state changed?
switch (newWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// new update available
showUpdateBar();
}
// No update available
break;
}
});
});
});
let refreshing;
navigator.serviceWorker.addEventListener('controllerchange', function () {
if (refreshing) return;
window.location.reload();
refreshing = true;
});
}
then in pushManager.js the code is like:
navigator.serviceWorker.register('sw.js')
.then(function (registration) {
messaging.useServiceWorker(registration);
// Request for permission
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
console.log('Token: ' + currentToken)
sendTokenToServer(currentToken);
// updateSubscriptionOnServer(currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
setTokenSentToServer(false);
}
})
......
The pushManagr.js is included in both login/index.html and index.html.
I think that calling navigator.serviceWorker.register at multiple places will have adverse effect.
so how I can combine the two instances into one.
If possible, remove the registration of the serviceworker from pushManager.
If you want the registration instance of the serviceworker,use the api getRegistration()
navigator.serviceWorker.getRegistration(/*scope*/).then(function(registration) {
if(registration){
// Move all your firebase messaging code to here
messaging.useServiceWorker(registration);
}
});
Why connection.hub.start() working but client.all.notify not working ?
my script
// signalr js code for start hub and send receive notification
var notificationHub = $.connection.notificationHub;
$.connection.hub.start().done(function () {
console.log('Notification hub started');
});
//signalr method for push server message to client
notificationHub.client.notify = function (message) {
if (message && message.toLowerCase() == "added") {
updateNotificationCount();
}
}
and
//Send Notification message to Client
var notificationHub = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
notificationHub.Clients.All.notify("added");
code Startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
I dont get notifications unless I write alterdatabase query and run it along with insert query
insert into Contact(Name,Email,Phone,Message,SentDate,Sender) values (N'Test' ,'test#gmail.com','0123456', 'Hello World', GETDATE(), 'Admin')
ALTER DATABASE database SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE ;
I had the same problem and I used jQuery version 3.5.1 and I changed it to 2.2.4 and it worked
I had the same problem and realized that you have to add the client methods first and then start hub.
You just use this code:
var notificationHub = $.connection.notificationHub;
notificationHub.client.notify = function (message) {
if (message && message.toLowerCase() == "added") {
updateNotificationCount();
}
}
$.connection.hub.start().done(function () {
console.log('Notification hub started');
});
I am new to JavaScript frameworks and currently trying to setup a falcor router calling an external api (for now consider it as an express api app + mango db, hosted at 3000 port).
Now, I am able to use the request package (commented out lines) and successfully call the Express Api app (which returns obj.rating = 4). But I am unable to send this value from the falcor router instead of the hard-coded value "5".
Below is the falcor-router's server.js code:
app.use('/rating.json', falcorExpress.dataSourceRoute(function (req, res) {
return new Router([
{
route: "rating",
get: function() {
var obj;
// request('http://localhost:3000/rating/101', function (error, response, body) {
// obj = JSON.parse(body);
// console.log('rating:', obj.rating); // obj.rating = 4
// });
return {path:["rating"], value:"5"};
}
}
]);
}));
The below is the code for index.html:
<script>
function showRating() {
var model = new falcor.Model({source: new falcor.HttpDataSource('http://localhost/rating.json') });
model.
get("rating").
then(function(response) {
document.getElementById('filmRating').innerText = JSON.stringify(response.json,null, 4);
});
}
</script>
I also tried to look at the global variable declaration, synchronize http request calls, promises, then statements etc. But nothing seemed to work, clearly I am missing out something here - not sure what.
The router's get handler expects the return value to be a promise or an observable that resolves to a pathValue. To get your request against the db to work, simply return a promise that resolves to a pathValue, e.g.
return new Router([
{
route: "rating",
get: function() {
return request('http://localhost:3000/rating/101', function (error, response, body) {
return { path: ["rating", value: JSON.parse(body).rating };
});
}
}
]);
In the below cloud code i would like to get a feedback of the saveAll function but after calling the code from my client in the parse Logs page i can only see:
I2014-10-08T15:28:32.930Z] v249: Ran cloud function acceptMeetingBis for user dyGu143Xho with:
Input: {"meetingId":"bUSTGNhOer"}
Result: Meeting accepted
Here is my cloud code:
Parse.Cloud.define("acceptMeetingBis", function(request, response) {
var userAcceptingTheMeeting = request.user;
var meetingId = request.params.meetingId;
var changedObjects = [];
var queryForMeeting = new Parse.Query("MeetingObject");
queryForMeeting.equalTo("objectId", meetingId);
queryForMeeting.first({
success: function(meeting) {
var userCreatorOfMeeting = meeting.get("user");
userAcceptingTheMeeting.increment("acceptedMeetings", +1);
changedObjects.push(userAcceptingTheMeeting);
meeting.add("participantsObjectId", userAcceptingTheMeeting.id);
if (meeting.get("participantsObjectId").length === meeting.get("meetingNumberOfPersons")) {
meeting.set("isAvailable", false);
}
changedObjects.push(meeting);
Parse.Object.saveAll(changedObjects, {
success: function(objects) {
console.log("Successfully saved objects"); //this line doesn't show up
response.success("objects saved");
},
error: function(error) {
// An error occurred while saving one of the objects.
response.error(error);
}
});
//future query and push notifications will go here
response.success("Meeting accepted");
},
error: function() {
response.error("Failed to accept the meeting");
}
});
});
I will also need to add some push and another nested query after the saveAll() but before doing/trying that i would like to know if this is the right method to use or if i have to build the code in a different way. I'm new to javascript and honestly i'm struggling to understand some concepts, like promises. Any help would be much appreciated.
Your call to
Parse.Object.saveAll
is asynchronous, and you call
response.success("Meeting accepted")
immediately after making the asynchronous call, which ends the cloud code running of the method. If you simply replace the
response.success("objects saved")
with
response.success("Meeting accepted")
you should get what you want.
I didn't see the rest of your question about promises. You should check out Parse's documentation on chaining promises, which is what you want here.
Essentially, here's what you'll want to do:
Parse.Cloud.define("acceptMeetingBis", function(request, response) {
var userAcceptingTheMeeting = request.user;
var meetingId = request.params.meetingId;
var changedObjects = [];
var meetingToAccept;
var queryForMeeting = new Parse.Query("MeetingObject");
queryForMeeting.get(meetingId).then(function(meeting) {
meetingToAccept = meeting;
var userCreatorOfMeeting = meeting.get("user");
userAcceptingTheMeeting.increment("acceptedMeetings", +1);
return userAcceptingTheMeeting.save();
}).then(function(userWhoAcceptedMeetingNowSaved) {
meetingToAccept.add("participantsObjectId", userWhoAcceptedMeetingNowSaved.id);
if (meetingToAccept.get("participantsObjectId").length === meetingToAccept.get("meetingNumberOfPersons")) {
meetingToAccept.set("isAvailable", false);
}
return meetingToAccept.save();
}).then(function(savedMeeting) {
response.success("Meeting accepted");
}, function(error) {
response.error("Failed to accept the meeting");
});
});
For each asynchronous action you want to do, perform it at the end of one of the .then functions and return the result (it returns a promise). Keep adding .then functions until you're done all the work you want to do, at which point call response.success.
I want to send data to a specific client. to do that I am trying with the following;
public Task GetWaitingOrdersCount(string id, string clientId)
{
DateTime today = Util.getCurrentDateTime();
var data = 10
return Clients.Client(Context.ConnectionId).loadOrders(data);
//return data;
}
In the above code, I want to send 'data' to the 'clientId' passed to this method.
BUT I m having an error in this line
return Clients.Client(Context.ConnectionId).loadOrders(data);
And the error is
'System.Threading.Tasks.Task<object>' does not contain a definition for 'loadOrders'
the client side code
con.loadOrders = function (data) {
loadOrders(data);
};
function loadOrders(data) {
$('#totalOrders').html(data);
}
Any help about the error???
EDIT:
This is my full client code..
<script type="text/javascript">
var con;
$(document).ready(function () {
con = $.connection.messagingHub;
$.connection.hub.start(function () {
var myClientId = $.connection.hub.id;
con.getWaitingOrdersCount('<%:ViewBag.rid%>',myClientId).done(function (data) {
console.log(data);
});
});
con.client.loadOrders = function (data) {
loadOrders(data);
};
});
function loadOrders(data) {
$('#totalOrders').html(data);
I just tried out your code (slightly modified) and it works fine for me. What version of SignalR are you using? Judging by your server code I'd say 1.0Alpha1+ but your client code looks more like 0.5.3, that is unless your con object is assigned to $.connection.yourhub.client;
If you update to SignalR 1.0Alpha2 and change your client code to be:
var con = $.connection.myCon;// This is arbitrary and would change based on your naming
con.client.loadOrders = function (data) {
loadOrders(data);
};
function loadOrders(data) {
$('#totalOrders').html(data);
}
That being said I believe your issue has to do with the version of SignalR you are using, server side that is: since you're receiving a task oriented error. Another piece of information that might be beneficial would be to know how GetWaitingOrdersCount is being called. Aka is it being invoked from the client directly via: con.server.getWaitingOrdersCount or is it being called from within the hub.
Hope this info helps!