When my client successfully connects to the hub, I want the client to immediately join a group. I have a method in my hub to do that, I just need an event handler for when the connection is established, just like
connection.start().done(
function () {
connection.invoke('JoinGroup', 'GroupName');
});
in SignalR for plain ASP.Net.
Can I do that or do I have to set a timer to do it after x seconds after the start(); call was made?
Edit:
I found out I can do
connection.start(
function (){
connection.invoke('JoinGroup', 'GroupName');
}
);
but it tells me that it Cannot send data if the connection is not in the 'Connected' State.
what do?
SignalR is notoriously difficult due to version mismatches etc.
Please see the following article: https://learn.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-2.1&tabs=visual-studio
In it, there's a section that specifies how to start (and wait for connection to be established):
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
connection.start().then(() => {
//try some stuff here :)
})
.catch(function (err) {
//failed to connect
return console.error(err.toString());
});
The javascript client uses promises that have to be resolved/rejected before you can use it.
The other option is to wrap inside async method and await the call (not sure if this will work correctly). Such as:
await connection.start();
//connection should be started now. beware of exceptions though
Related
I have this in my code:
useEffect(() => {
if(loaded2 == false){
connection = signalr.hubConnection('https://webambe.com/xxx');
connection.logging = true;
proxy = connection.createHubProxy('xxx');
//receives broadcast messages from a hub function, called "helloApp"
proxy.on('updateAll', (argOne) => {
setAlertNum(1);
//Here I could respond by calling something else on the server...
});
// atempt connection, and handle errors
connection.start().done(() => {
//console.log("dddd" + proxy.connectionState);
setLoaded2(true);
//console.log('Now connected, connection ID=' + connection.id);
setTrans(false);
}).fail(() => {
//console.log('Failed');
});
//connection-handling
connection.connectionSlow(() => {
//console.log('We are currently experiencing difficulties with the connection.')
});
connection.error((error) => {
const errorMessage = error.message;
let detailedError = '';
if (error.source && error.source._response) {
detailedError = error.source._response;
}
if (detailedError === 'An SSL error has occurred and a secure connection to the server cannot be made.') {
//console.log('When using react-native-signalr on ios with http remember to enable http in App Transport Security https://github.com/olofd/react-native-signalr/issues/14')
}
//console.debug('SignalR error: ' + errorMessage, detailedError)
});
}
});
When the code hits connection.start().done((), then the connection should be established but when I hit the send button that invokes the hub i get this error (setLoaded2(true) means that the connection is established):
Connection has not been fully initialized. Use .start().done() to run the logic after
connection has started.
But I have stated that says that connection has started here:
setLoaded2(true);
When this is called setTrans(false) is called to get rid of the transparent view so users can interact with the UI.
The hub connects successfully and I can run commands to the server and back, but I just want to know how to say when the connection is established so that the user can use the system.
I'm not sure if this is the way it shud be done but its working and staying connected when I move the connection and proxy outside my functional component:
connection = signalr.hubConnection('https://webambe.com/xxx');
connection.logging = true;
proxy = connection.createHubProxy('xxx');
when added this code outside the component the connection stays connected and no issues with signalr
So its happened for the second time now. I believe what triggered the error was when I tried to do an update to my MongoDb server but I still don't know why this happens and I'd like to find out.
Basically I am sending json string data from a C# script to my front end with Signalr using this command:
_hubContext.Clients.All.SendAsync("ReceiveMail", json);
The issue is that my script keeps broadcasting this message (without any errors or issues) but my client side doesnt receive it (even though this broadcast has worked for weeks....). When I change the name of the broadcast to something different the data then makes its way to the client side perfectly.
Example:
//This broadcast worked fine for weeks but suddenly stopped working (without error)
_hubContext.Clients.All.SendAsync("ReceiveMail", json);
//Changed above broadcast to this and broadcast works perfectly fine again
_hubContext.Clients.All.SendAsync("ListenForMail", json);
TS Code:
constructor() {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:57697/chat')
.build();
this.hubConnection
.start()
.then(() => this.table())
.catch(err => console.log('Error while establishing connection :('));
this.hubConnection.on('ReceiveMail', (mailJson: string) => {
this.loadEmail(mailJson);
});
this.hubConnection.on('ReceiveConnection', (msg: string) => {
console.log('Connection: ' + msg);
});
}
Anyone have any insight into this issue?
The method name the C# code is calling doesn't match the methods you are listening for in the TS code - but I'll assume that's a typo. If it's not, then you need to make sure the .on methods use the same method names as the C# code.
Another thing you do need to change is where you start the connection E.G.
constructor() {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:57697/chat')
.build();
this.hubConnection.on('RetrieveMail', (mailJson: string) => {
this.loadEmail(mailJson);
});
this.hubConnection.on('ReceiveConnection', (msg: string) => {
console.log('Connection: ' + msg);
});
this.hubConnection
.start()
.then(() => this.table())
.catch(err => console.log('Error while establishing connection :('));
}
In the code above I have moved the .start() call to AFTER registering the on methods. You should do it this way because the hubconnection can start listening messages before the handlers are registered causing a race condition. Any messages sent won't be received if the on handler hasn't finished registering.
I am implementing a Network Test for my Web-application using OpenTok's js library.
To do that, I create a publisher, connect to session, then make a subscriber connect to the publisher's stream.
The Test is working on other browsers (I have tested Chrome and Internet Explorer) but on Firefox version 57.0.1 I get an error - 'The stream was unable to connect due to a network error. Make sure you have a stable network connection and that it isn't blocked by a firewall.'
Make sure when you create the OpenTok Session you are using a 'routed' Session, not a 'relayed' one. Also make sure you are passing the 'testNetwork' property to the subscribe method. Here is a working sample:
// Sample code
var session = OT.initSession(APIKEY, SESSIONID);
session.connect(TOKEN, function(err) {
if (err) {
alert(err.message);
return;
}
var publisher = session.publish();
publisher.on('streamCreated', function(event) {
session.subscribe(event.stream, null, {
testNetwork: true
}, function(err) {
if (err) alert(err.message);
});
});
});
https://jsbin.com/quruzac/edit
I am trying to connect to Local SQL Server database using Tedious in node js.
function connectToSql() {
sqlConnection.on('connect', function (err) {
// If no error, then good to go...
if (err) {
console.log(err);
} else {
console.log('connected to SQL!');
executeSelectStatement();
}
});
}
When I am invoking this function soon after its declaration, its working fine and prints 'connected to SQL!'. But when I am calling this function "connection" event of SocketIO.Server its not making sql call. My code is as below:
ioServer.on('connection', function (socket: SocketIO.Socket) {
console.log('a user connected');
connectToSql();
});
it only prints 'a user connected'
Any suggestions why is this happening?
It is likely that the SQL connection has already been established before the Socket.io connection takes place. That being the case, the connect event has probably already happened.
If you're looking to only establish the SQL connection after receiving a Socket.io connection, you probably need to new Connection(config); at that time while also subscribing to the connect event.
Do note that you probably do not want to establish an SQL connection for every Socket.io connection as with multiple people utilizing the application, a lot of additional overhead is taking place where it likely does not need to.
We are seeing a surprising scenario when we are on a slow network connection and our calls to the WL Server time out.
This happens at WL.Client.connect as well as on invokeProcedure:
we execute the call with a timeout of 10 seconds
the network connection is slow so the call times out
the defined onFailure procedure associated to that call is executed
the WL Server responds with a valid response after the timeout
the onSuccess procedure associated to that call is executed
Is this the designed and intended behavior of the WL Client Framework? Is this specified in the InfoCenter documentation or somewhere?
All developers in our team expected these two procedures to be exclusive and our code was implemented based on this assumption. We are now investigating options on how to match a timed-out/failed response to a success response to make sure we achieve an exclusive execution of onFailure or onSuccess code/logic in our app.
Note: we did not test that with connectOnStartup=true and since the initOptions does not provide an onSuccess procedure (since WL handles that internally) it might be even harder to implement an exclusive execution in this case.
That seems like expected behavior, but don't quote me on that.
You can get the behavior you want (only call the failure callback when it fails, and only call the success callback when it succeeds) using jQuery.Deferreds. There are ways of creating these deferred objects with dojo and other libraries. But, I just tested with jQuery's implementation, which is shipped with every version of IBM Worklight.
$(function () {
var WL = {};
WL.Client = {};
WL.Client.invokeProcedureMock = function (options) {
options.onFailure('failure');
options.onSuccess('success');
};
var dfd = $.Deferred();
var options = {
onSuccess: dfd.resolve,
onFailure: dfd.reject
};
WL.Client.invokeProcedureMock(options);
dfd
.done(function (msg) {
// handle invokeProcedure success
console.log(msg);
})
.fail(function (msg) {
//handle invokeProcedure failure
console.log(msg);
});
});
I put the code above in a JSFiddle, notice that even if I call the onSuccess callback, it won't have any effect because I already called the failure callback (which rejected the deferred). You would add your application logic inside the .done or .fail blocks.
This is just a suggestion, there are likely many ways to approach your issue.