microsoft/BotFramework-DirectLineJS

Catch failing connection to directline WebSocket endpoint

Jakob-vdH opened this issue · 3 comments

I am trying to figure out a way to catch failing connections to the WebSocket stream endpoint of directline (for example wss://europe.directline.botframework.com/v3/directline/conversations/...) to be able to fall back to the polling mechanism.

Use case example: In some corporate networks WebSocket stream connections are blocked by a proxy etc or some plugins block WebSocket streams. If that is the case (resulting in a console error by direcline.js that the connection could not be established) I want to fall back to the polling so the affected users are still able to use the bot.

I already have the functioning fallback if the directline connectionStatus is 4 / FailedToConnect resulting in the DIRECT_LINE/CONNECT_REJECTED action in the store. But if the connection via wss fails, the directline connectionStatus is still 2 / Online resulting in the DIRECT_LINE/CONNECT_FULFILLED store action. Also the directline object including the connectionStatus object does not change when the error is thrown and connectionStatus.hasError stays false and the connectionStatus.thrownError stays null. Directline then tries again to establish a connection every few seconds.

This scenario can be reproduced in combination with the webchat by using for example the uBlock Origin browser plugin and setting a filter to block websockets (add *$websocket to My filters). To get the connections status one can use the following line directLine.connectionStatus$.subscribe(connectionStatus => {}) and listen to the actions in a store middleware of the webchat.

Is it expected behavior that the connectionStatus does not change on the failing wss connection?
I would be glad if you could help me figure out, how I am able to catch that the connection has failed.
Thank you very much.

@Jakob-vdH,

As you know, ConnectionStatus is a function of Direct Line and reports the status of the connection it and the Direct Line channel is maintaining. However, if that connection is broken, the Direct Line object used by Web Chat (or any client) won’t be able to report that status until the connection is re-established. Once re-established, the various store action types (for instance, DIRECT_LINE/DISCONNECT_PENDING) will then be able to respond, but only after the fact.

In simpler terms, imagine the power unexpectedly going out at your home. You may have an alert set up at your home to say, “Hey, the power is about to drop!”, but because of the unexpected nature, the power drops before the alert can fire and there is no way to delay it from happening. The alert can’t fire until the power (connection) is back up, after the fact.

I’ve been able to test the above in Web Chat, successfully. However, because 1) Direct Line’s default is to attempt to reconnect when the wss stream fails, 2) it does not fallback to polling, and 3) it doesn’t report the status until the connection has been restored, there is no Web Chat / Direct Line method for live capturing a failed connection.

@stevkan thank you for clarifying.
I am still wondering why the ConnectionStatus is 2 / Online, even though the wss connection has not been established yet, since in this use case it has been blocked from the beginning. Like in your example, why does it say we have power, even though we never had any.
I understand the case though when an existing connection is interrupted/broken.

Is there a way to "manually" test, if a wss connection to directline can be established, so we could tell the webchat if it is able to use wss? Otherwise, my first idea would be to host a simple echo server to run a wss connection test against, before establishing the directline connection.
Or do you know of best practices for such scenarios by any chance?

Thank you very much for your help and time.

@Jakob-vdH, thank you for your patience. The reason ConnectionStatus shows as 2 / Online is because that is the last known status when the web socket fails. And, because the connection is no longer functional, it is unable to update to a more proper status. In fact, the Direct Line client has no functionality what so ever, at this point.

Unfortunately, I do not know of a method to manually test the wss connection. Without further research, I don't have a better suggestion than your idea to host a server to test the connection beforehand.