Hub events not available - signalr

I am getting the following error when trying to subscribe to a SignalR hub event:
$.connection.hub.connectionSlow is not a function
My code:
var connection = $.hubConnection();
serviceRequestHubProxy = connection.createHubProxy('myHub');
connection.start()
.done(function () { alert('connected!'); });
$.connection.hub.connectionSlow(function () {
alert('connection slow!');
});
I am using SignalR 2.2. What am I doing wrong?

When you're not using generated proxy, $.connection will not be available. You should change to.
var connection = $.hubConnection();
serviceRequestHubProxy = connection.createHubProxy('myHub');
connection.start()
.done(function () { alert('connected!'); });
connection.connectionSlow(function () {
console.log('We are currently experiencing difficulties with the connection.')
});
Read more

Related

sending request via Fetch API from ASP.NET razor view

I'm trying to send a request via Feth
ch API to the remote api that serves over Http. I'm getting this error on my developer tools window.
Here is js.
(function () {
login();
})();
function login() {
document.getElementById("submitBtn").addEventListener("click", function () {
sendLoginAjax();
});
};
function sendLoginAjax(userName, password) {
var form = document.getElementById("loginForm");
var params = "UserName=" + userName + "&Password" + password + "&IPs=";
// Bind the FormData object and the form element
const FD = new FormData();
FD.append("func", "Login");
FD.append("params", params);
fetch("http://isapi.mekashron.com/soapclient/soapclient.php?URL=http://isapi.icu-tech.com/icutech-test.dll%2Fwsdl%2FIICUTech", {
method: 'POST',
body: FD
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
}
I don't know what I should do to solve it.
Have any fix?

K6 trigger ASP.NET Core server function

I have an ASP.NET Core Web API project that is using SignalR, I have a hub there which I am connecting to it using k6 (I want to do some load testings) I manage to connect to my hub but I can not figure out how to call a function from my server, my code is
import ws from 'k6/ws';
import { check } from 'k6';
export default function () {
var token = "Bearer userAccessToken";
const url = 'wss://localhost:5001/session';
const params = { headers: { "Authorization": token } };
const res = ws.connect(url, params, function (socket) {
socket.on('open', () => {
console.log("opened");
socket.send(JSON.stringify({ UserId: "aUserId", GameId: "AGameId" }))
});
socket.on('close', () => console.log('disconnected'));
});
check(res, { 'status is 101': (r) => r && r.status === 101 });
}
My function is called joinGameSession and it takes two variables the user id and the gameId
public async Task<bool> JoinGameSession(JoinGameRequest request)
{
return true;
}
I have managed to trigger functions using Microsoft's SignalR client.
const signalR = require("#microsoft/signalr");
require('dotenv').config();
var token = process.env.token ?? "";
var questionIndex = 0;
let connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5000/session", { headers: { "Authorization": token } })
.withAutomaticReconnect()
.build();
connection.start().then(() => {
connection.invoke("JoinGameSession", { UserId: "a", GameId: "x" });
}).catch(e => {
console.log(e);
})
but I can not do it with k6, is there any other tools to achieve my goal?
Thank you.

SignalR Multiple Hub Connection .NET Core

I have 2 Hub classes,
SystemNotificationHub.cs
public class SystemNotificationHub : Hub { }
QuotationChatHub.cs
public class QuotationChatHub: Hub { }
SystemNotificationHub is defined in _Layout.cshtml so user is connected to hub continously,
and when user enters to QuotationChat.cshtml page, I want also same user to connect the QuotationChatHub, so in a simple manner I'd like the user to connect multiple hubs at the same time.
I cannot let user to connect more than 1 hub at the same time. How can I achive this?
StartUp endPoint Configurations
endpoints.MapHub<SystemNotificationHub>("/systemNotificationHub");
endpoints.MapHub<QuotationHub>("/quotationHub");
quotationChat.js
$(function () {
if (connection === null) {
connection = new signalR.HubConnectionBuilder()
.withUrl("/quotationHub")
.build();
connection.start().then(function () {
document.getElementById('sendButton').onclick = function () {
connection.invoke("BroadcastFromClient")
.catch(function (err) {
return console.error(err.toString());
});
};
});
}
});
notification.js
$(function () {
if (connection === null) {
connection = new signalR.HubConnectionBuilder()
.withUrl("/systemNotificationHub")
.build();
connection.on("Notify", function (response) {
});
connection.on("HubError", function (response) {
alert(response.error);
});
connection.start().then(function () {
connection.invoke("NotificationMethod")
.catch(function (err) {
return console.error(err.toString());
});
});
}
});
As far as I know, this issue is related with your if condition in your codes.
You have checked connection is null or not before creating the connection builder. But all two js use the same connection model.
To solve this issue, I suggest you could try to create a new connection for systemNotificationHub for example connection1 and then your code will work well.
More details, you could refer to below codes:
quotationChat.js not changed.
notification.js:
//Define a new connection1 as the new js object as connection
$(function () {
if (connection1 === null) {
connection1 = new signalR.HubConnectionBuilder()
.withUrl("/systemNotificationHub")
.build();
connection1.on("Notify", function (response) {
});
connection1.on("HubError", function (response) {
alert(response.error);
});
connection1.start().then(function () {
connection.invoke("NotificationMethod")
.catch(function (err) {
return console.error(err.toString());
});
});
}
});

Signal-R Calling another server method after receiving previous call data

I am just reading the Microsoft tutorial on Signal-R and want to use it instead of Ajax in .Net Core, Considering the following code from Microsoft, Is there any way we can do another server call, after receiving data from the first call in the broadcastMessage function (that is defined as a javascript function)?
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
</script>
So that we can examine data received and conditionally initiate another call.
Or if all server calls should be put inside $.connection.hub.start().done(function () {?
You can call other methods after the message is received like this:
TypeScript example:
//Start connection with message controller
public startConnectionMessage = () => {
this.hubMessageConnection = new signalR.HubConnectionBuilder()
.configureLogging(signalR.LogLevel.Debug)
.withUrl('http://localhost:20000/notifications')
.build();
this.hubMessageConnection
.start()
.then(() => {
//after connection started
console.log('Notifications Service connection started!');
// Start the Group Listener.
this.addTranferGroupMessageListener();
// Get ConnectionID.
this.GetConnectionID();
})
.catch(err => console.log('Error while starting connection: ' + err))
}
// Group channel listner.
public addTranferGroupMessageListener = () => {
this.hubMessageConnection.on("groupMessage", (data: any) => {
console.log(data);
});
}
private GetConnectionID() {
this.hubMessageConnection.invoke("GetConnectionID")
.then((connectionID: string) => {
console.log("Recived connectionID = " + connectionID);
// call the method to register AppContextData.
this.sendApplicationContextData(connectionID)
}).catch((error: Error) => {
console.log("Error: " + error);
})
}
private sendApplicationContextData(connectionID: string) {
// add the received connectionID to the payload.
this.connection.ConnectionID = connectionID;
console.log("Sending ApplicationData.");
console.log(this.connection);
//inovke server side method to pass AppContext data.
this.hubMessageConnection.invoke("RegisterAppContextData", this.connection)
.then()
.catch((error: Error) => {
console.log("Error: " + error);
});
}
You can see that after connection is established, I invok a hub method that simply returns me a connectionID and based on connectionID I invoke another method sending that parameter. The server side hub methods are:
public string GetConnectionID()
{
return this.Context.ConnectionId;
}
public async Task RegisterAppContextData(AppContextData data)
{
// Calls the groups Manager.
await this.MapClientToGroups(data);
}

Evothings and ddp

We are trying to connect our evothings app up to a meteor server.
To do this we are using a lib called asteroid. However we are unable to connect and run methods. We are absolutly sure this is not a server issue since we have some separate client code for testing that works flawlessly with it.
Evothings says it should work with websockets, and we aren't getting any error output, but all our method calls are returning nothing.
Here is the code:
var _asteroid = require('asteroid');
var Asteroid = (0, _asteroid.createClass)('password-login');
var asteroid = new Asteroid({ endpoint: 'wss://[url]/websocket' });
var currentLogin = null;
$('#login').submit(function(event) {
event.preventDefault();
login($('#login_username').val(), $('#login_password').val());
});
$('#create').submit(function(event) {
event.preventDefault();
newUser($('#create_username').val(), $('#create_password').val(), $('#create_id').val());
});
$('#occupy').click(function(event) {
setStatus(0);
});
$('#vacant').click(function(event) {
setStatus(1);
});
$('#refreash').click(function() {
getEmptyRooms();
});
window.newUser = function (username, password, roomId) {
$('#create_error').text('');
asteroid.call("accounts.newUser", username, password, roomId).then(function (result) {
console.log("Success");
login(username, password);
}).catch(function (error) {
console.log("Error");
console.error(error);
$('#create_error').text(error.message);
});
}
window.login = function (username, password) {
$('#login_error').text('');
asteroid.loginWithPassword({ username: username, password: password }).then(function (result) {
console.log(result);
currentLogin = result;
$('#current').html('Current User: ' + username);
}).catch(function (error) {
console.log("Error");
console.error(error);
$('#login_error').text(error.message);
});;
}
window.getEmptyRooms = function () {
asteroid.call("rooms.getAvailable").then(function (result) {
console.log(result);
$('#room_list').empty();
for(i = 0; i < result.length; i++) {
$('#room_list').append('<li>' + result[i] + '</li>');
}
}).catch(function (error) {
console.log("Error");
console.error(error);
});
}
window.setStatus = function (status) {
$('#status_error').text('');
if (currentLogin != null) {
asteroid.call("rooms.setStatus", status).then(function (result) {
console.log(result);
}).catch(function (error) {
console.log("Error");
console.error(error);
$('#status_error').text(error.message);
});
} else {
console.log('please login first');
$('#status_error').text('please login first');
}
}
As far as I know, the require() function works only in node.js, not in browser environment such as Evothings Viewer or Cordova, so you'll need some alternative means of loading the "asteroid" lib. Browserify?
How did you look for error output? The Evothings Tools window? If so, did you add this snippet to your index.html file?
<script>
// Redirect console.log to Evothings Workbench.
if (window.hyper && window.hyper.log) { console.log = hyper.log }
</script>
Perhaps this error isn't exclusive to the Evothings environment. Have you tested the app in a regular web browser?
Are you using proper certs?
Self signed will not work. The Evothings app is served via wss and since it runs "headless" so to speak (not a normal browser) it can't ask the user about allowing a self signed cert, so it will fail. Note that AFAIK ANY issue with the cert will make it fail.

Resources