I'm looking at Elm and in particular the WebSocket library. With the high level functions, "[T]he effect manager tries to reconnect with an exponential backoff strategy." That is all well and good, but if there is something truly wrong with the client or the server (say the server is down, or is trying to tell the client to login before opening the websocket). Simply trying again more and more slowly will never fix the problem.
Is there some way to get messages about the status of the websocket's connection so that I can show the user a helpful message like "The server is down." or "Authentication is required for this feature." and the like?
I imagine it working something like:
subscriptions model =
listen "ws://echo.websocket.org" WSMessage
status "ws://echo.websocket.org" WSStatus
There is an open issue and proposed patch that covers this case, but at the moment there is not a solution that works in the approved WebSocket library.
(This answer current as of September 28, 2017)
Related
We are building a bot using the MS Bot Framework. Sometimes when the bot is not used, it takes too much time to respond and we get a [500] Internal Server Error. We see this issue when we try to access the bot on our app (we are using Direct Line to interact with the bot).
I've read other answers about making sure the Microsoft Azure setting for application activity is set to "Always On", and we have done this. But as Always on is pinging the root of our bot web app, I think it may not be enough to keep the bot / directline alive...
And I don't have any rewrite rules from http to https preventing the ping request to be successful..
Anybody had this issue?
UPDATE to ask a specific question : How can we make sure that our bot is ALWAYS alive if all the settings explained above do not work ? Should we ping our bot thru the directline framework ?
One way to do it would be to send a ping every 15 minutes. The default code even gives you a place to handle the ping in the message controller
else if (message.Type == ActivityTypes.Ping)
{
}
please also take a look at this post as it may work for you and is a very simple solution with no code.
I had to create an azure function that pings my service, as I was having this same problem. I have Always On for all my services, and still find the bot going to sleep. With the ping service, it establishes a new conversation, sends the utterance, and then closes after receiving the response. This has seemed to work, but is only a week into practice. Note, I am pinging every five minutes.
I have an application in which clients use websockets to connect to a server which is running Spring Boot Tomcat.
My question is if there is a way for the server to detect a client disconnect due to a network loss.
Thanks.
if you are using stomp , check SessionDisconnectEvent.
For raw Websocket connections, you can use :
WebSocketHandler-->afterConnectionClosed
I have searched before for this and the solution I was able to find was to implement a ping-pong mechanism between the server and the clients.
For example, each few seconds send a dummy message to the client on a specific topic and receive back another dummy reply, if you didn't get a reply for a configured period you can consider the client disconnected.
As mentioned here,
STOMP and Spring also allow us to set up topics, where every
subscriber will receive the same message. This is going to be very
useful for tracking active users. In the UI, each user subscribes to a
topic that reports back which users are active, and in our example
that topic will produce a message every 2 seconds. The client will
reply to every message containing a list of users with its own
heartbeat, which then updates the message being sent to other clients.
If a client hasn't checked in for more than 5 seconds (i.e. missed two
heartbeats), we consider them offline. This gives us near real time
resolution of users being available to chat. Users will appear in a
box on the left hand side of the screen, clicking on a name will pull
up a chat window for them, and names with an envelope next to them
have new messages.
I would like to do some one way streaming of data and am experimenting with SSE vs Websockets.
Using SSE form a golang server I'm finding it confusing on how to notify the client when sessions are finished. (eg the server has finished sending the events or the server suddenly goes offline or client looses connectivity)
One thing I need is to reliably know when these disconnect situations. Without using timeouts etc.
My experiments so far , when I take the server offline the client gets EOF. But I'm having trouble trying to figure out how to signal from the server to the client that a connection is closed / finished and then how to handle / read it? Is EOF a reliable way to determine a closed / error / finished state?
Many of the examples with SSE fail to show client good client connection handling.
Would this be easier with Websockets?
Any experiences suggestions most appreciated.
Thanks
The SSE standard requires that the browser reconnect, automatically, after N seconds, if the connection is lost or if the server deliberately closes the socket. (N defaults to 5 in Firefox, 3 in Chrome and Safari, last time I checked.) So, if that is desirable, you don't need to do anything. (In WebSockets you would have to implement this kind of reconnect for yourself.)
If that kind of reconnect is not desirable, you should instead send a message back to the client, saying "the show is over, go away". E.g. if you are streaming financial data, you might send that on a Friday evening, when the markets shut. The client should then intercept this message and close the connection from its side. (The socket will then disappear, so the server process will automatically get closed.)
In JavaScript, and assuming you are using JSON to send data, that would look something like:
var es = EventSource("/datasource");
es.addEventListener("message", function(e){
var d = JSON.parse(e.data);
if(d.shutdownRequest){
es.close();
es=null;
//Tell user what just happened.
}
else{
//Normal processing here
}
},false);
UPDATE:
You can find out when the reconnects are happening, by listening for the "close" event, then looking at the e.target.readyState
es.addEventListener("error", handleError, false);
function handleError(e){
if(e.target.readyState == 0)console.log("Reconnecting...");
if(e.target.readyState == 2)console.log("Giving up.");
}
No other information is available, but more importantly it cannot tell the difference between your server process deliberately closing the connection, your web server crashing, or your client's internet connection going down.
One other thing you can customize is the retry time, by having the the server send a retry:NN message. So if you don't want quick reconnections, but instead want at least 60 seconds between any reconnect attempts do this have your server send retry:60.
Me and my friend having a little bit of a problem using websockets, I'll quickly explain so we maybe could get it working.
We got a websocket server up and running and its doing fine, lisening to a specific port and connects all our clients as it should.
But we would like to have channels. For an example: http://www.example.com/channel/682831
And we can't figure out how to solve that, because right now its like "broadcasting" and we would more likely have "multicasting"
where we could say this message is going there and this message is going here.
So please help us.
Thanks!
WebSocket provides point-to-point raw messaging. What you describe usually runs under the term "Publish & Subscribe".
A subscriber signals it's interest in a topic, publisher send events to that topic, and a broker dispatches events to the right clients based on a book of subscriptions it maintains.
This needs to be layered on top of WebSocket. You might have a look at WAMP, an open standard WebSocket based protocol that provides Publish & Subscribe (as well as Remote Procedure Calls).
Disclosure: I am original author of WAMP (now an open community effort) and work for Tavendo.
I've developed a web-based application in which a signed in user should send a message to the server telling he is still online every 3 seconds. The message is then processed by the server and a stored procedure is called in Mysql to set the user's status to online.
I've looked in to similar issues in which Comet and Ajax are compared (here or here) but considering that 3 second delay is acceptable and maximum users of 1000 are online in the system, is using Ajax a wise choice or Comet should be used?
For this kind of feature comet is more appropriate:
Your clients send messages (i'm online)
Your server broadcast the processed message (user X is still online)
In an ajax way you are only serving messages to server.
In order to get the "broadcast effect" in an ajax way. You will end up doing something similar to comet but with less efficient bandwidth.
Ajax:
Client send server - i'm in
Server process
Server send back to client list of user in.
In this case every client ask every 3 second the database for the COMPLETE "in" list.
In comet:
Client X send server - i'm in
Server process
Server send back to client S that user X is still online
In this case every client tell the server every 3 second that he is in.
The server send back to every connected client ONLY that x is still in
Comet is just the technique to broadcast back and push messages to client
Ajax is the technique to push client information to the server without having to refresh all the page.
Quoting wikipedia:
http://en.wikipedia.org/wiki/Comet_%28programming%29
Comet is known by several other names, including Ajax Push, Reverse Ajax , Two-way-web, HTTP Streaming,and HTTP server push among others.
So go comet :)
If you do not broadcast anything, then simple Ajax is the best option
In this particular case, since you do not need to send any information from the server to the client(s), I believe Ajax is the more appropriate solution. Every three seconds, the client tells the server it is connected, the database is updated, and you're done.
It could certainly be done using Comet, in which case you would basically ping each registered client to see if it is still connected. But, you would still need to run a query on the database for each client that responds, plus you would still need the client to notify the server on its initial connection. So, it seems to me that Comet would be more trouble than it's worth. The only thing that might make sense is if you could ping each registered client and store the responses in memory, then once all clients have been pinged you can run one single query to update all of their statuses. This would give you the added bonus of knowing as soon as a client disconnects as opposed to waiting for a timeout. Unfortunately, that is beyond the scope of my expertise with Comet so, at this point, I can't help to actually implement it.