SignalR Connection fails in Iphone safari browser gets minimized. How to make it stay connected ? or How to Reconnect when Tab gets active - asp.net-core

I am using Signal-R Core, a simple chat page. I logged in with different clients like browser in laptop, mobile browser both Android and IOS,
I could able to send message to all clients, But when mobile browser(only IOS) gets minimized Signal-R connection disconnected,
I've tried implementing a logic to reconnect. Idea is to set a flag on connection.close() get called, And then starting the connection by calling connection.start() on Window.focus() get called. Window.focus() function is working properly.
This works as 1 after 1 time the browser minimized, Only on iPhone browser.
Scenario : Initially connected, message sent successfully.
Now browser minimized, and then opened again and sending message from iPhone client, now gets failed.
Then again minimized and opened again the browser, sending from iPhone client, now message sent successfully.
Tried it multiple times. works same.
var flagConnection = true;
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
connection.on("BroadcastMessage", function ( user, message) {
var encodedMsg = user + ": " + message;
var li = document.createElement("li");
li.textContent = encodedMsg;
$("#divChatMessages").append(li);
});
connection.start();
connection.onclose(function(change) {
if(connection.connectionState == 0)
flagConnection = false;
else
flagConnection = true;
});
window.addEventListener("focus", function(event)
{
if(flagConnection == false){
connection.start();
flagConnection = true;
}
});

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.

WebSockets not working when application is built

I have got to ASP.NET-Core 2.0 apps communicating via WebSockets.
App A is Server.
Application A is running on a remote server with Ubuntu.
App B is Client
Application B is running on a PC setup in my office.
When I test my applications locally in Debug everything works fine. Client connects to the server and they can exchange information.
However, when I build my Server app, Client can connect to it but when server tries to send a message to the client the message is not received by the client.
public async Task<RecievedResult> RecieveAsync(CancellationToken cancellationToken)
{
RecievedResult endResult;
var buffer = new byte[Connection.ReceiveChunkSize];
WebSocketReceiveResult result;
MemoryStream memoryStream = new MemoryStream();
do
{
if (cancellationToken.IsCancellationRequested)
{
throw new TaskCanceledException();
}
Console.WriteLine("Server Invoke");
// result never finishes when application is build. On debug it finishes and method returns the correct result
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
if (result.MessageType == WebSocketMessageType.Close)
{
await CloseAsync(cancellationToken);
endResult = new RecievedResult(null, true);
return endResult;
}
memoryStream.Write(buffer, 0, result.Count);
} while (!result.EndOfMessage);
endResult = new RecievedResult(memoryStream, false);
return endResult;
}
This is the part of code where everything hangs.
What I tried was:
Build Server - Build Client => not working
Build Server - Debug Client => not working
Debug Server - Debug Client => working
I need any advice what might be wrong here and where I should look for issues.
Console if free of errors. Everything hangs on:
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);

OpenTok - Subscriber failed to subscribe to a stream in a reasonable amount of time

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

How to capture SignalR native client losing connection with server

I am working on a .net client application which utilizes SignalR. I want to notify the user if the connection is down for some reason. How can I capture the disconnect event using the native client?
The client will go into the reconnecting when the connection dies.
Therefore you can tie into the Reconnecting event to see when the connection goes down:
var connection = new Connection("http://myEndPointURL");
connection.Reconnecting += () =>
{
Console.WriteLine("The connection has gone down, shifting into reconnecting state");
};
Hope this helps!
I was able to capture StateChanged to detect changes in the connection and notify the user.
connection.StateChanged += (statechange) =>
{
Console.WriteLine("Changing from " + statechange.OldState + " to " + statechange.NewState);
};
This gives me a mechanism to notify the user when the connection is dropped or successfully reconnected.