SignalR error when invoking method on the server from JavaScript client - javascript

I have a C# server running my hub class, which contains only 1 method in there, which is as follows,
public class HothHub : Hub
{
public async Task AddSingleUserGroup(string name)
{
await Groups.AddToGroupAsync(Context.ConnectionId, name);
}
}
I also have a JavaScript client, which connects to the hub via the following code,
var connection;
async function signalRStart() {
connection = new signalR.HubConnectionBuilder()
.withUrl("https://somesignalrurl.com/hothhub", { withCredentials: false })
.withAutomaticReconnect()
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("hothHubToHothUpdate", () => {
console.log("Called by the server!");
});
connection.onreconnecting(error => {
console.log("Connection lost due to error " + error + ". Reconnecting.");
});
// Start the connection.
await start();
}
async function start() {
try {
await connection.start();
connection.invoke("addSingleUserGroup", "someUniqueUserName");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
Now when the client initiates the connections and run start() on itself, this part seems to run fine. A connection to the signalR hub is made successfully. The problem I'm having is when connection.invoke("addSingleUserGroup", "someUniqueUserName"); is run although the error does not happen all the time. On first run, the method at the server end is hit successfully however, it looks like subsequent calls to it fail and this is the error returned in the client,
Uncaught (in promise) Error: Failed to invoke 'addSingleUserGroup' due to an error on the server. HubException: Method does not exist.
at _callbacks.<computed> (signalr.js:1252:36)
at HubConnection._processIncomingData (signalr.js:1364:33)
at HubConnection.connection.onreceive (signalr.js:985:52)
at webSocket.onmessage (signalr.js:2236:30)
I've read a few articles on here but most seemed to be related to the client calling the wrong method name having used a capital letter at the start of the method name when invoking it and some having mentioned issues with the method expecting 1 type parameter and receiving another type although in my instance here its hard to think how the server would not treat the incoming parameter as a string, which is what is being passed in. Has anyone got any ideas on what could be wrong here or what I could try?
Thanks!

Unfortunately I dont have an actual answer for this but after deploying the solution to my Azure App Service, the release version does not produce the error. It seems the error only persisted when in debug mode but like I said I'am not sure why.

Related

(javascript) Unable to return value received in Socket.on(event)

Basically I have a client side code that sends data to the server, the server responds with data which calls a socket.on(event) in the client side code. Within the function that is immediately run I can log the received data but I cannot return it to outside for the life of me.
function receive_data(){
socket.off('Sent_data_to_client').on('Sent_data_to_client',(player_info));
console.log(player_info)
}
If i try to log player_info it tells me it is undefined "Uncaught (in promise) ReferenceError: player_info is not defined". I want to return player_info as the result of the receive_data function but it is undefined.
I am new to javascript and Socket.Io as a whole, i apologise for any obvious mistakes made.
Sockets in JS doesnt work like this. Have a specifics events.
https://nodejs.org/api/net.html#new-netsocketoptions
This is the Node JS documentation, but it doesn't matter because Node JS is based on "V8 engine", that is, it's the same.
As you can see in the documentation it indicates that there are a series of events that the socket can handle, among them the 'data', calling a callback function where you implement the necessary logic for your code.
In this case, for example:
const net = require('net');
const socket = new net.Socket();
// Open a socket connection with example.com
socket.connect(80, 'example.com', () => {
console.log('Connected');
});
socket.on('data', (data) => {
console.log(`Recived: ${data}`);
});
socket.on('error', (error) => {
console.log(`Error: ${error}`);
});
You should change the function definition to accept an argument, which will be the data that the server sends.
function receive_data(){
socket.off('Sent_data_to_client').on('Sent_data_to_client', function(player_info) {
console.log(player_info);
return player_info;
});
}

Is there a way to mock a property on a request object

I have a Javascript REST api endpoint defined using swagger. In my controller, I am logging the IP address from the incoming request.
This is functioning just fine but now I am trying to add Jest tests for coverage and each time I run my test I am getting an error thrown
module.exports.execute = async function execute (req, res) {
try {
log.info("Start processing request from client IP="+req.connection.remoteAddress);
... do some stuff
log.info("Finished processing request from client IP="+req.connection.remoteAddress);
} catch(err) {
log.error("Error caught in Address controller =>" + err.message);
utils.writeJson(res, err.message, 500);
}
};
When I execute my tests, I am getting Error caught in controller =>Cannot read property 'remoteAddress' of undefined
When I comment out the lines that call req.connection.remoteAddress, all is good and I get coverage but not for those 2 lines.
I am guessing the issue is that the req.connection.remoteAddress is a property and not a function.
Is there a way I can mock the response from this call to return a statis string like 1.1.1.1 ?
Any help is appreciated
After thinking about the question in the first comment from #Will Alexander, I added this (second line) and now all is good. Thank you Will
let mockReq = _.set({},'swagger.params.entity.value', JSON.stringify({ fail: false}));
mockReq.connection = _.set({},'remoteAddress', '1.1.1.1');

Parse custom webhook: can I query my tables?

In a Parse custom webhook, which is of the form:
app.post('/receiveSMS', function(req, res) {
Where receiveSMS is hooked up to the Twilio api and this method is properly called (I have logs to prove it), but I'm trying to query on my tables within this method and it doesn't seem to be working.
Is this allowed, or is there anything special I need to do to make this work?
var contactObj = Parse.Object.extend("Contact");
var contactQuery = new Parse.Query(contactObj);
console.log(req.body.From);
contactQuery.each(function(contact) {
and the body of the each call never gets called.
Is this allowed, and if so, what am I doing wrong here?
Update -- The entirety of the webhook code block is:
app.post('/receiveSMS', function(req, res) {
console.log('receive SMS');
console.log(req.body.Body);
res.send('Success');
if(req.body.Body.toLowerCase() == "in" || req.body.Body.toLowerCase() == "out") {
twilio.sendSMS({
From: "(xxx) xxx-xxxx",
To: req.body.From,
Body: "It's been noted, and notifications have been sent. Check us out!"
}, {
success: function(httpResponse) {
console.log(httpResponse);
response.success("SMS Sent!");
},
error: function(httpResponse) {
console.error(httpResponse);
response.error("Uh OH, something went wrong");
}
});
if(req.body.Body.toLowerCase() == "in") {
console.log("in was received");
// eventQuery
var contactObj = Parse.Object.extend("Contact");
var contactQuery = new Parse.Query(contactObj);
console.log(req.body.From);
// contactQuery.equalTo("phone", req.body.From);
contactQuery.first({
success: function(contact) {
console.log("found contact");
console.log(contact);
}, error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
}
});
This code is called and the logs "console.log('receive SMS')" and the like are all called, except for what is inside the query's first call.
Queries on tables is fine, but you can't use the each() function, as that is restricted to only work in background jobs.
You'll have to use find() or first() or get() depending on your needs.
UPDATE
OK, after seeing your full code I have some ideas as to why it isn't working. First off you're sending res.send("Success"); before you're finished, I'm not positive but I think this causes it to stop running the rest of your code (haven't checked, could be wrong).
Also you're doing multiple async operations without chaining them so the contactQuery.first() will run before the twilio.sendSMS() is finished.
Inside twilio.sendSMS() you're calling response.success() / response.error(). These are for cloud methods, not web hooks, so I expect these would be throwing errors server-side (check the logs on the Dashboard).
Inside contactQuery.first() you are using alert() which isn't supported in cloud code.
I'm not sure if those mistakes will be caught early and throw errors or if they'll raise run-time exceptions, but they should be fixed, your code re-deployed and try again. Then report any errors in the server logs.
Yes, it's allowed, I'm using the same web hooks.
My guess is that you probably have defined security restriction on your Contact class that prevent the query to fetch anything. What's the security setting on this class ?
You can either try to relax the constrains, or login as a dummy user, and execute the query (approach that I chose).
cheers
-A

In Meteor Method, why is this.connection.clientAddress undefined?

// on server
Meteor.methods({
'getIP': function () {
return this.connection.clientAddress;
}
});
// on client
Meteor.startup(function() {
Meteor.call('getIP', function (err, res) {
console.log(res); // returns undefined
});
});
digging further, it seems 'this.connection' on the server only has 3 things: id, close, onClose, but not clientAddress. What am I missing?
Additional info:
Running vagrant on windows host with
ubuntu remote.
I tried setting the environment variable HTTP_FORWARDED_COUNT to 0,
1, and 2 but no luck.
doc reference: http://docs.meteor.com/#publish_connection
I'm using Meteor 0.9.3.1 and calling this.connection.clientAddress inside a Meteor method is working for me. I store the client IP address as a field in a Collection set I'm working with.
I did have one problem, the client was trying to simulate the call and was throwing the Exception while simulating the effect of invoking... this.connection is undefined error. But I noticed my documents were getting stored correctly with the correct client IP address. So the fix is to just not have the client try to simulate this.
In my Meteor method I just added a Meteor.isServer check. It shouldn't matter if the client simulates the client IP being 0.0.0.0:
var ip = "0.0.0.0";
if(Meteor.isServer) {
if(!this.connection.clientAddress)
throw new Meteor.Error(403, "Server Error: You must be connected.");
else
ip = this.connection.clientAddress;
}
// ...store document with ip...
And everything works as intended.

How do I fix: InvalidOperationException upon Session timeout in Ajax WebService call

We are invoking Asp.Net ajax web service from the client side. So the JavaScript functions have calls like:
// The function to alter the server side state object and set the selected node for the case tree.
function JSMethod(caseId, url)
{
Sample.XYZ.Method(param1, param2, OnMethodReturn);
}
function OnMethodReturn(result)
{
var sessionExpiry = CheckForSessionExpiry(result);
var error = CheckForErrors(result);
... process result
}
And on the server side in the ".asmx.cs" file:
namespace Sample
[ScriptService]
class XYZ : WebService
{
[WebMethod(EnableSession = true)]
public string Method(string param1, string param2)
{
if (SessionExpired())
{
return sessionExpiredMessage;
}
.
.
.
}
}
The website is setup to use form based authentication. Now if the session has expired and then the JavaScript function "JSMethod" is invoked,
then the following error is obtained:
Microsoft JScript runtime error: Sys.Net.WebServiceFailedException: The server method 'Method' failed with the following error: System.InvalidOperationException-- Authentication failed.
This exception is raised by method "function Sys$Net$WebServiceProxy$invoke" in file "ScriptResource.axd":
function Sys$Net$WebServiceProxy$invoke
{
.
.
.
{
// In debug mode, if no error was registered, display some trace information
var error;
if (result && errorObj) {
// If we got a result, we're likely dealing with an error in the method itself
error = result.get_exceptionType() + "-- " + result.get_message();
}
else {
// Otherwise, it's probably a 'top-level' error, in which case we dump the
// whole response in the trace
error = response.get_responseData();
}
// DevDiv 89485: throw, not alert()
throw Sys.Net.WebServiceProxy._createFailedError(methodName, String.format(Sys.Res.webServiceFailed, methodName, error));
}
So the problem is that the exception is raised even before "Method" is invoked, the exception occurs during the creation of the Web Proxy. Any ideas on how to resolve this problem
You have a callback method (OnMethodReturn) specified in the WebMethod call, but not an error handler method. You need to create one and pass it into as you do the callback method. Then you can handle your failed WebMethod calls in there.
This problem occurs even before the Ajax framework can invoke the target method, it fails while creating the web proxy. Anyway I solved the problem by enabling Anonymous access to the Web Service folder and checking for Session explicitly in the Web Service methods
Why not use, try { } catch { } around your JS method call?
try this one...use "static"
[WebMethod(EnableSession = true)]
public static string Method(string param1, string param2)

Categories

Resources