How to determine server disconnection from SignalR client? - javascript

How can a SignalR JavaScript client detect when a connection with the server is lost?

A hub has a method disconnect which will allow you to add a callback when disconnection takes place:
myHub.disconnect(function() {
alert('Server has disconnected');
});
If you aren't using hubs then the code for the disconnect method will help you out:
$(connection).bind("onDisconnect", function (e, data) {
callback.call(connection);
});
This shows the syntax for hooking onto the onDisconnect event of the underlying connection.

If you are using hubs then implement the IDisconnect interface.
public class ChatHub : Hub, IDisconnect
{
public void Disconnect()
{
Debug.WriteLine(Context.ConnectionId + " disconnected");
}
}
On persistent connections you can override OnDisconnectAsync,
(from the SignalR wiki at https://github.com/SignalR/SignalR/wiki/PersistentConnection )
public class MyEndPoint : PersistentConnection
{
protected override Task OnDisconnectAsync(string clientId)
{
return Connection.Broadcast("Client " + clientId + " disconncted");
}
}

This worked for me using "#aspnet/signalr": "^1.0.0" npm package
const connection = new signalr.HubConnectionBuilder()
.withUrl('url')
.configureLogging(signalr.LogLevel.Information)
.build()
connection.onclose(() => {
// close logic goes here
})

The SignalR 2.0 way of doing this is like so:
$.connection.hub.disconnected(function () {
console.log('Connection disconnected')
});
http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client#connectionlifetime

Starting with SignalR v0.5.1 it works this way:
$.connection.hub.stateChanged(function (change) {
if (change.newState === $.signalR.connectionState.reconnecting) {
console.log("liveFeed is reconnecting!");
}
else if (change.newState === $.signalR.connectionState.connected) {
console.log("liveFeed is connected!");
}
});
For more details check this website:
http://weblogs.asp.net/davidfowler/archive/2012/06/10/signalr-0-5-1-released.aspx

The below, worked for me:
var connection = $.hubConnection('signalrConnectionUrl');
connection.disconnected(function() {
console.log('Connection disconnected');
});
I'm using version: 2.1.2
See the following link for reference: Link

The provided answers will no longer work.
This is the new way to stop/disconnect connections.
myHub.stop().then(() => {
alert('Server has disconnected');
});

Related

How to send message from node.js server to Android app?

Im trying to make a simple application. That is When I write a word at edittext in android app such as "Hi", Then android app send message "Hi" to node.js server and node.js server send message "Hi has sent successflly" to android app. This is just a example, actually my object is android send a data(message) to server, and receive another data(message) from server.
The problem is this. When I write a word at android app and press button, the message transmitted successfully(I can confirm by console at node.js). But I cant send message to android from node.js .. When I press send button, My android app shut down..
What android says is "java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Activity.runOnUiThread(java.lang.Runnable)' on a null object reference" ..
Yesterday, this error didn't happened and another error occured. "cannot cast string to JSONObject."
I will show you my code.
Server Side(Node.js)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = 12000;
app.get('/', function(req, res) {
res.sendFile('index.html');
})
io.on('connection', function(socket) {
console.log('Android device has been connected');
socket.on('message', function(data) {
console.log('message from Android : ' + data);
Object.keys(io.sockets.sockets);
Object.keys(io.sockets.sockets).forEach(function (id) {
console.log("ID : ", id );
io.to(id).emit('message', data);
console.log(data + ' has sent successfully');
})
/*if (data != null) {
io.emit('message', {message : data + ' has received successfully'});
}*/
})
socket.on('disconnect', function() {
console.log('Android device has been disconnected');
})
})
http.listen(port, function() {
console.log('Server Start at port number ' + port);
})
Client Side (Android)
private Emitter.Listener handleIncomingMessages = new Emitter.Listener(){
#Override
public void call(final Object... args){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject) args[0];
String message;
try {
message = data.getString("text").toString();
Log.i("result", message);
addMessage(message);
} catch (JSONException e) {
Log.e("result", "Error : JSONException");
return;
} catch (ClassCastException e) {
Log.e("result", "Error : ClassCastException");
e.printStackTrace();
return;
}
}
});
}
};
private void sendMessage(){
String message = mInputMessageView.getText().toString().trim();
mInputMessageView.setText("");
addMessage(message);
JSONObject sendText = new JSONObject();
try{
sendText.put("text", message);
socket.emit("message", message);
}catch(JSONException e){
}
}
private void addMessage(String message) {
mMessages.add(new Message.Builder(Message.TYPE_MESSAGE)
.message(message).build());
// mAdapter = new MessageAdapter(mMessages);
mAdapter = new MessageAdapter( mMessages);
mAdapter.notifyItemInserted(0);
scrollToBottom();
}
private void scrollToBottom() {
mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
}
I already searched similar problems that other people asked, but It didn't give me solution. Please help me. Thank you for reading long question.
p.s Because Im not English speaker, Im not good at English .. There will be many problems at grammar and writing skills. Thanks for understanding...
Reason this happens is because method getActivity() returns null. This might happen if you run this on a fragment after it is detached from an activity or activity is no longer visible. I would do a normal null check before like:
Activity activity = getActivity();
if(activity != null) {
activity.runOnUiThread(new Runnable() {...}
}
I'm not familiar with socket.emit() method but it might throw network exception since it's running on UI thread and you are not allowed to do that. I recommend using RxJava/RxAndroid if you want to do this on another thread.
If you want to do network operation just use it like this:
Observable
.fromRunnable(new Runnable {
void run() {
// here do your work
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Void>() {
#Override
public void onCompleted() {
// not really needed here
}
#Override
public void onError(Throwable e) {
// handle errors on UI thread
}
#Override
public void onNext(Void void) {
// do something on UI thread after run is done
}
});
Basically what it does it calls method call from Callable you just made on separate thread and when it's over it invokes onNext method if no exception was thrown or onError method if exception was thrown from Subscriber class.
Note that Response class isn't part of the RxJava/RxAndroid API and you can make it if you want. You can make it a simple POJO class or anything else you need it to be. If you don't need to have response you can use Runnable instead of Callable and it will work just fine.
In order for this to work you need to add this dependencies to your modules Gradle file:
dependencies {
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.6'
}

SOCKJS client - Detect server is unreachable

I'm using vertxbus that internally built upon sockjs and I have a basic question.
When I call 'onopen' for the first time in order to establish a connection, How can I know that server is down?
At this point when I call 'onopen' and pass a callback function - if server is down the method is stuck and doesn't return at all.
Thanks!
You can check this code , where I'm using EventBus.
Here is the Reference code
this.eventBus = new EventBus(this.URL);
this.eventBus.onopen = (e) => {
this._opened = true;
console.log("open connection");
this.callHandlers('open', e);
this.eventBus.publish("http://localhost:8082", "USER LOGIN INFO");
this.eventBus.registerHandler("http://localhost:8081/pushNotification", function (error, message) {
console.log(message.body);
//$("<div title='Basic dialog'>Test message</div>").dialog();
});
}
this.eventBus.onclose = (e) => {
this.callHandlers('close', e);
}
}

JavaScript callbacks function object

i try to learn node.js and try to create a new TCP Server connection. The code
var server = require('net').createServer(function(socket) {
console.log('new connection');
socket.setEncoding('utf8');
socket.write("Hello! You can start typing. Type 'quit' to exit.\n");
socket.on('data', function(data) {
console.log('got:', data.toString());
if (data.trim().toLowerCase() === 'quit') {
socket.write('Bye bye!');
return socket.end();
}
socket.write(data);
});
socket.on('end', function() {
console.log('Client connection ended');
});
}).listen(4001);
look at the callback function, after then, they call listen method. What is this for kind of object.
What it basically says is:
function myHandler(socket) {
// everything up to socket.on('end')
}
var server = require('net').createServer(myHandler);
server.listen(4001);
So it's just creating a socket server with a handler function, and then make the server listen to port 4001.

Socket IO reconnect?

How to reconnect to socket io once disconnect has been called?
Here's the code
function initSocket(__bool){
if(__bool == true){
socket = io.connect('http://xxx.xxx.xxx.xxx:8081', {secure:false});
socket.on('connect', function(){console.log('connected')});
socket.on('disconnect', function (){console.log('disconnected')});
}else{
socket.disconnect();
socket = null;
}
}
If I do initSocket(true), it works. If I do initSocket(false), it disconnects. BUT THEN if I try to reconnect using initSocket(true), the connection does not work anymore. How can I get the connection to work?
Well, you have an option here ...
The first time you initialize the socket value you should connect with io.connect,
The next time ( after you've called disconnect once ), you should connect back with socket.socket.connect().
So your initSocket, should be something like
function initSocket(__bool){
if(__bool){
if ( !socket ) {
socket = io.connect('http://xxx.xxx.xxx.xxx:8081', {secure:false});
socket.on('connect', function(){console.log('connected')});
socket.on('disconnect', function (){console.log('disconnected')});
} else {
socket.socket.connect(); // Yep, socket.socket ( 2 times )
}
}else{
socket.disconnect();
// socket = null; <<< We don't need this anymore
}
}
I know you already have an answer, but I arrived here because the socket.IO client reconnection feature is broken in node at the moment.
Active bugs on the github repo show that lots of people aren't getting events on connect failure, and reconnect isn't happening automatically.
To work around this, you can create a manual reconnect loop as follows:
var socketClient = socketioClient.connect(socketHost)
var tryReconnect = function(){
if (socketClient.socket.connected === false &&
socketClient.socket.connecting === false) {
// use a connect() or reconnect() here if you want
socketClient.socket.connect()
}
}
var intervalID = setInterval(tryReconnect, 2000)
socketClient.on('connect', function () {
// once client connects, clear the reconnection interval function
clearInterval(intervalID)
//... do other stuff
})
You can reconnect by following client side config.
// 0.9 socket.io version
io.connect(SERVER_IP,{'force new connection':true });
// 1.0 socket.io version
io.connect(SERVER_IP,{'forceNew':true });
This is an old question, but I was struggling with this recently and stumbled here. Most recent versions of socket.io (>2.0) doesn't have the socket.socket property anymore as pointed out here.
I am using socket.io-client 2.2.0 and I was facing a situation where the socket seems to be connected (property socket.connected = true) but it wasn't communicating with the server.
So, to fix that, my solution was call socket.close()and socket.open. These commands force a disconnection and a new connection.
I had an issue with socket-io reconnect. May be this case will help someone. I had code like this:
var io = require('socket.io').listen(8080);
DB.connect(function () {
io.sockets.on('connection', function (socket) {
initSockets(socket);
});
});
this is wrong, becase there is a delay between open port assigned callbacks. Some of messages may be lost before DB gets initialized. The right way to fix it is:
var io = null;
DB.connect(function () {
io = require('socket.io').listen(8080);
io.sockets.on('connection', function (socket) {
console.log("On connection");
initSockets(socket);
});
});

How to use Websockets with Pyramid and socket.io?

I'm trying to create a simple WebSocket application using Pyramid and socket.io frameworks.
Server-side code:
from pyramid.response import Response
from pyramid_socketio.io import SocketIOContext, socketio_manage
import gevent
def includeme(config):
'''
This method is called on the application startup.
'''
config.add_route('socket.io', 'socket.io/*remaining')
class ConnectIOContext(SocketIOContext):
# self.io is the Socket.IO socket
# self.request is the request
def msg_connect(self, msg):
print "Connect message received", msg
self.msg("connected", hello="world")
# Socket.IO implementation
#view_config(route_name="socket.io")
def socketio_service(request):
print "Socket.IO request running"
print request
retval = socketio_manage(ConnectIOContext(request))
return Response(retval)
Client code:
<script>
var socket = null;
$(document).ready(function() {
socket = new io.Socket(null, null);
socket.on('connect', function() {
console.log("Connected");
socket.send({type: "connect", userid: 123});
});
socket.on('message', function(obj) {
console.log("Message received");
console.log("Message", JSON.stringify(obj));
if (obj.type == "some") {
console.log("do some");
}
});
socket.on('error', function(obj) {
console.log("Error", JSON.stringify(obj));
});
socket.on('disconnect', function() {
console.log("Disconnected");
});
console.log("Connecting...");
socket.connect();
});
</script>
I need this code to use web-sockets for the connection, but it falls back to XHR-polling.
How can I fix it?
Thanks in advance, Ivan.
You probably want to look at the latest release of gevent-socketio, and its documentation at http://gevent-socketio.readthedocs.org/
A major overhaul was done at the PyCon 2012 sprints, by John Anderson, Sébastien Béal and myself.
You may also have a look at pyramid_sockjs. It integrates well with Pyramid and uses sockjs that fulfills the same role of socket.io and is arguably simpler to understand.

Categories