How to intercept, in react-native, the signalR error 'Error: Server timeout elapsed without receiving a message from the server.'? - react-native

I'm using in react-native the package #aspnet/signalr to connect with my server.
All work correctly until the app is in foreground, I'm able to reconnect if I lose the connection without receiving errors.
When I open the app after a long time in in background I can reconnect immediately to my server but I receive the error Error: Connection disconnected with error 'Error: Server timeout elapsed without receiving a message from the server.'
How can I intercept this error?
This is a piece of my code:
connection = new signalR.HubConnectionBuilder()
.withUrl("http://192.168.xxx.xxx/notificationHub?userId=" + authInfo.userId)
.build();
connection.on("receiveMessage", data => {
console.log('*** MESSAGGIO RICEVUTO ***');
Alert.alert(data);
});
connection.start()
.then(() => console.log("Connessione avvenuta"))
.catch((err) => console.log(err);
connection.onclose()
.then(() => connection.start(););
Thanks

Error: Connection disconnected with error 'Error: Server timeout elapsed without receiving a message from the server.'
The default timeout value of serverTimeoutInMilliseconds is 30,000 milliseconds (30 seconds), if this timeout elapses without receiving any messages from the server, the connection might be terminated with above error.
To troubleshoot the issue, please check if you just update KeepAliveInterval setting of your SignalR hub but not change the serverTimeoutInMilliseconds value on your client side.
And the recommended serverTimeoutInMilliseconds value is double the KeepAliveInterval value.
Update:
Is there a way to intercept this error and manage the error without warning?
If you do not want the signalR client log this error in browser console tab, you can try to modify the LogLevel to None.
.configureLogging(signalR.LogLevel.None)
Then manage error in onclose callbacks, like below.
connection.onclose(error => {
//...
console.log("Connection Disconnected");
});

Related

React Native Signalr keeps saying connection needs to be initialized

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

Ratchet PHP server establishes connection, but Kotlin never receives acknowledgement

I have a ratchet server, that I try to access via Websocket. It is similar to the tutorial: logging when there is a new client or when it receives a message. The Ratchet server reports having successfully established a connection while the Kotlin client does not (the connection event in Kotlin is never fired). I am using the socket-io-java module v.2.0.1. The client shows a timeout after the specified timeout time, gets detached at the server and attaches again after a short while, just as it seems to think, the connection did not properly connect (because of a missing connection response?).
The successful connection confirmation gets reported to the client, if the client is a Websocket-Client in the JS-console of Chrome, but not to my Kotlin app. Even an Android emulator running on the same computer doesn´t get a response (So I think the problem is not wi-fi related).
The connection works fine with JS, completing the full handshake, but with an Android app it only reaches the server, but never the client again.
That´s my server code:
<?php
namespace agroSMS\Websockets;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
class SocketConnection implements MessageComponentInterface
{
protected \SplObjectStorage $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
error_log("New client attached");
}
function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
error_log("Client detached");
}
function onError(ConnectionInterface $conn, \Exception $e)
{
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
function onMessage(ConnectionInterface $from, $msg)
{
error_log("Received message: $msg");
// TODO: Implement onMessage() method.
}
}
And the script that I run in the terminal:
<?php
use Ratchet\Server\IoServer;
use agroSMS\Websockets\SocketConnection;
use Ratchet\WebSocket\WsServer;
use Ratchet\Http\HttpServer;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new SocketConnection()
)
)
);
$server->run();
What I run in the browser for tests (returns "Connection established" in Chrome, but for some reason not in the Browser "Brave"):
var conn = new WebSocket('ws://<my-ip>:80');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
What my Kotlin-code looks like:
try {
val uri = URI.create("ws://<my-ip>:80")
val options = IO.Options.builder()
.setTimeout(60000)
.setTransports(arrayOf(WebSocket.NAME))
.build()
socket = IO.socket(uri, options)
socket.connect()
.on(Socket.EVENT_CONNECT) {
Log.d(TAG, "[INFO] Connection established")
socket.send(jsonObject)
}
.once(Socket.EVENT_CONNECT_ERROR) {
val itString = gson.toJson(it)
Log.d(TAG, itString)
}
}catch(e : Exception) {
Log.e(TAG, e.toString())
}
After a minute the Kotlin code logs a "timeout"-error, detaches from the server, and attaches again.
When I stop the script on the server, it then gives an error: "connection reset, websocket error" (which makes sense, but why doesn´t he get the connection in the first time?)
I also tried to "just" change the protocol to "wss" in the url, in case it might be the problem, even though my server doesn´t even work with SSL, but this just gave me another error:
[{"cause":{"bytesTransferred":0,"detailMessage":"Read timed out","stackTrace":[],"suppressedExceptions":[]},"detailMessage":"websocket error","stackTrace":[],"suppressedExceptions":[]}]
And the connection isn´t even established at the server. So this try has been more like a down-grade.
I went to the github page of socket.io-java-client to find a solution to my problem there and it turned out, the whole problem was, that I misunderstood a very important concept:
That socket.io uses Websockets doesn´t mean it is compatible with Websockets.
So speaking in clear words:
If you use socket.io at client side, you also need to use it at the server side and vice versa. Since socket.io sends a lot of meta data with its packets, a pure Websocket-server will accept their connection establishment, but his acknowledgement coming back will not be accepted by the socket.io client.
You have to go for either full socket.io or full pure Websockets.

Socket.io rooms is not getting message

I have two file in a nodejs- express application
first.pug
var socket = io.connect('//'+document.location.hostname+':'+document.location.port, {
query: {
token: "XXXXXX"
}
});
socket.on('connect', (s) => {
console.log('connected!');
socket.emit('join123', 'room1');
});
second.pug
var socket = io.connect('//'+document.location.hostname+':'+document.location.port, {
query: {
token: "XXXXXX"
}
});
socket.on('join123', function (data) {
console.log("join.group========================"+data);
});
Nodejs Server side
io.on('connection', (socket) => {
console.log('a user connected');
socket.join('join123');
});
I dont see any message in second.pug when a message is pulished from first.pug
The socket.io connection made by second.pug never receives a message because your server never sends it a message.
Here's what first.pug does:
It creates a socket.io connection to your server.
When that connection succeeds, it sends a join123 message to that server.
Here's what your socket.io server does:
It listens for connecting clients.
When a client connects, it puts that client into the join123 room.
No messages are sent out to any of the connected clients.
Note: there is no listener on the server for the join123 message that the client sent so likely something is wrong there.
Here's what second.pug does:
It create a socket.io connection to your server.
It listens for a join123 message to be sent to it.
But, nothing ever sends a join123 message to second.pug, so second.pug never receives that message. first.pug sends a join123 message to your server, but the server never sends that to anyone else. The act of doing socket.join('join123') does not cause any messages to be sent. It just adds the socket to a room by that name. If you want the second.pug to get a join123 message, you would have to write code on your server that actually sends that message either to all connections or somehow just to the second.pug connection.

When connecting to Pop3 server with Mailkit, connection fails every other time

I'm trying to write some code to retrieve the e-mails stored in the pop3 mailbox hosted at a third party email provider using Mailkit (version 2.1.0.3). When attempting to connect to the mailserver, the connection fails every other time with the error:
"An error occurred while attempting to establish an SSL or TLS
connection."
With inner exception
"Authentication failed because the remote party has closed the transport stream."
So the code above on the first attempt succeeds, and on the second attempt fails with the error mentioned above. This happens without fail, and always fails the second time I try. This leads me to believe there is something wrong with terminating the connection.
Here is the code I use to set up a connection.
using (var client = new Pop3Client())
{
await client.ConnectAsync("pop3.**.nl", 995, true); // FAILS HERE
await client.AuthenticateAsync("**username**", "**password**");
for (int i = 0; i < client.Count; i++)
{
...
}
await client.DeleteAllMessagesAsync();
await client.DisconnectAsync(true);
}
I already attempting resolving the issue using the following functions, however, none of them helped. However changing the SSL protocol to version SSL3 and SSL2 caused the error to appear at every connection attempt, instead of every other one.
client.ServerCertificateValidationCallback += (e, r, t, y) => true;
client.SslProtocols = SslProtocols.Tls12;
client.CheckCertificateRevocation = false;

SignalR Core call function when connection is established

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