React Native Signalr keeps saying connection needs to be initialized - react-native

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

Related

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.

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

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;
}
});

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

SignalR Asp.Net Core Send Async Hanging

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.

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