-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reconnect option? #69
Comments
apparently you need to send a ping frame every now and then, to keep things running http://stackoverflow.com/questions/10585355/sending-websocket-ping-pong-frame-from-browser |
fair enough - i ll have to solve this on the app side then |
I just realized I was having related issues, and was just checking if there was an existing ticket. The ws library that this websocket-stream depends on has a ws.ping method, so i'll try that. This seems to be the relevant part of the spec: https://html.spec.whatwg.org/multipage/network.html#ping-and-pong-frames edit: Socket.io (or rather Engine.io) has a built-in pingInterval, which is why I never knew about this. |
I think this might be a good feature to add here, so it's solved for Max, Mathias, what do you think?
|
since ping is part of the spec i'd merge a PR that adds pinging to keep the socket alive |
@mcollina wouldn't a simple setInterval be fine here? |
Probably :). But it would waste bandwidth (sending a ping when it's not On second thought, the best approach here is to expose the internal ping()
|
@mcollina you could skip the ping if a write was performed since the last time you pinged and still use setInterval (at max you'd ping/send data every 2x interval) |
@mafintosh yeah :D. My usecase is probably a little too specific, (in MQTT doing 2x is invalid) What's the interval for Websockets, @binarykitchen? |
@binarykitchen @AdrianRossouw would you like to assemble a PR with that 25000 value as a default? |
@mcollina after ~60 seconds of inactivity the ... you asking me to do a PR using your |
I was actually trying to write a test that proves that it times out first, so that we know the setInterval and ping/pong resolves it. Maybe its something that only comes to place when an actual browser is involved, and the test will need to be something zuul-selenium related? Also kind of sucks having a 1 minute timeout in a test, so I was seeing if something like time-mock or sinonjs would be able to help. I was also spending some time learning how the code in WS works around this stuff. |
Just make the timeout configurable - then the test can just use a 100ms timeout and there is no need to mock |
@binarykitchen the setInterval thing that @mafintosh pointed out was good. @AdrianRossouw having a unit test is awesome. A simple solution to test this is to accept a |
@binarykitchen can you tell me more about which browser you are using? I haven't been able to reproduce the timeout when running with webstream-socket running on node on both sides. The reason I'm asking is because I'm wondering whether the ping interval needs to go on the server or on the client side. |
@AdrianRossouw FF v39 |
@AdrianRossouw I think this should go in the client side, and probably only on browser. |
Yeah, so i don't think this is really possible in a standards compliant way (stackoverflow reference) The ping/pong methods have not been exposed on the browser's WebSocket implementations, which is what WS falls back to. You can add your own higher level ping/pong messages, which is how engine.io does it, but that feels a bit dirty. I'll think about it a bit more before I hack up a solution. |
Basically, the reason why I never experienced this is because I use MQTT.js with its own keepalive mechanism. Awesome :). So, it seems this is not really fixable in this module. |
So, a reconnect won't be implemented and @mcollina, are you suggesting I should use MQTT.js instead? |
Or would you really accept if I do a good PR? |
I investigate this a bit more:
I think we can accept a PR that exposes the setInterval(function () {
wsstream.ping()
}, 10000) Remember to clear up the interval when the stream ends. I think you can wrap all this into a nice module 'websocket-stream-pingpong', which we can link from here, if anybody else needs it. |
Alright, I ll think about it when I have time ... |
Okay, I just started to write a module but somehow fail to simulate such a timeout in my tests. Why isn't it occuring? Here is the current, experimental test code var http = require('http'),
test = require('tape'),
websocketStream = require('websocket-stream'),
WebSocketServer = require('ws').Server,
test('get disconnected', function(t) {
var server = http.createServer(),
wss = new WebSocketServer({server: server})
server.listen(8344, function() {
var clientStream = websocketStream('ws://localhost:8344')
wss.on('connection', function(ws) {
var serverStream = websocketStream(ws)
setTimeout(function() {
console.log('server wants to play ...')
serverStream.write('server wants to play')
}, 2 * 60 * 1000) // usually, websockets time out after 60 seconds
setTimeout(function() {
console.log('client wants to play ...')
clientStream.write('client wants to play')
}, 3 * 60 * 1000) // usually, websockets time out after 60 seconds
// this never happens but why??
serverStream.on('error', function(err) {
t.equal(err.toString(), 'Error: write after end', 'server stream timed out')
})
// this never happens but why??
clientStream.on('error', function(err) {
t.equal(err.toString(), 'Error: write after end', 'client stream timed out')
clientStream.destroy()
serverStream.destroy()
t.end()
})
})
})
}) |
@binarykitchen the problem is that's a browser thing, not a websocket one. The browser kills the ws connection if it's inactive (probably for good reasons). |
@mcollina Right, the browser. How would you write such a test case then?? |
probably using something like zuul and sauce labs. |
not sauce labs. must be testable on localhost from command line without the need for an internet connection. |
zuul is a test runner that will allow you to run your mocha etc. tests in browser locally, as well as being able to use sauce labs when run automatically from travis. locally it can run via a browser you open, or via phantomjs. |
does phantomjs kill the ws connection if it's inactive? |
Folks, to run tests in the browser: https://github.com/maxogden/websocket-stream#run-the-tests |
@mcollina i see, could do that - but isn't there an easier solution to automate this all in the console? |
@mcollina I fail to reproduce the timeout in a test environment with Beefy. Check out this unfinished package: Run There is no timeout between Beefy and the server. Why? |
Maybe Beefy does some pings? chrisdickinson/beefy#93 |
Unfortunately I have little time till mid-September (after nodeconf.eu) |
okay, i ll wait until end of september then - really need your help and advice by then. grazie! |
Your test is failing on my machine - no error is emitted. I'm not following what that code should prove. |
@mcollina exactly. after 60 seconds there should be a timeout. hence writing data from client to server after 70 seconds should emit an error here https://github.com/binarykitchen/websocket-stream-ping-pong/blob/master/test_client.js#L16 but this isn't happening. test fail because why? |
I presume the timeout is much higher. You should probably dig into the websocket spec and/or a browser source code to find out. |
I already did and found nothing useful. Most sources say the timeout is 60 seconds. Maybe Beefy already does something with websockets and is messing with the test case? |
Try without beefy. |
How do you suggest to run the tests in browser + server then? |
browserify directly and serve using some static module. |
Just did that. No luck, but I guess it is an nginx issue: Figuring out how to set up a test environment for that. |
I do not have much background info on this one problem but I think the websocket-stream emits the
end
event after a certain timeout of inactivity.Is this a well-known case? Can it reconnect when needed, i.E. with an option? Or better, on a
.write()
call?The text was updated successfully, but these errors were encountered: