Gspia
Gspia

Reputation: 809

Capturing refresh on haskell websockets example server?

The websockets server example works as expected. On browser refresh (e.g. S-F5 with chrome), the websocket disconnects, still working as expected. After refresh, the user has to give name again to connect to the server.

How would you capture the refresh-event and keep the user connected? E.g. Is this doable only on server side or does the client require modifications as well? Haskell examples or links to such would be nice as well as hints on how to do this!

Upvotes: 1

Views: 82

Answers (1)

Michal Charemza
Michal Charemza

Reputation: 27012

How would you capture the refresh-event...

There isn't really such a thing as a refresh event to detect (I would love to be proved wrong in this!)

... and keep the user connected...

The refresh, or rather, the leaving of the page before loading it again, causes the websocket to disconnect, and (especially if this is the only page on the site that is open), there isn't really much you can do about it.

So the only thing that can be done, is have some sort of auto-reconnect the next time the page loads. A solution that allows this is one where..

  • when the name is initially entered, the name is saved somewhere in the browser;
  • when the page reloads, it checks for a previously saved name;
  • and if it's found, it connects again using that name.

Local storage is one such place to save this, as in the below example, modified from https://github.com/jaspervdj/websockets/tree/master/example to save/retrieve the name from local storage.

$(document).ready(function () {
    var savedUser = sessionStorage.getItem("rejoin-user");
    if (savedUser) {
        joinChat(savedUser);
    }

    $('#join-form').submit(function () {
        joinChat($('#user').val())
    });

    function joinChat(user) {
        sessionStorage.setItem("rejoin-user", user);
        $('#warnings').html('');
        var ws = createChatSocket();

        ws.onopen = function() {
            ws.send('Hi! I am ' + user);
        };

        ws.onmessage = function(event) {
            if(event.data.match('^Welcome! Users: ')) {
                /* Calculate the list of initial users */
                var str = event.data.replace(/^Welcome! Users: /, '');
                if(str != "") {
                    users = str.split(", ");
                    refreshUsers();
                }

                $('#join-section').hide();
                $('#chat-section').show();
                $('#users-section').show();

                ws.onmessage = onMessage;

                $('#message-form').submit(function () {
                    var text = $('#text').val();
                    ws.send(text);
                    $('#text').val('');
                    return false;
                });
            } else {
                $('#warnings').append(event.data);
                ws.close();
            }
        };

        $('#join').append('Connecting...');

        return false;
    };
});

... Is this doable only on server side or does the client require modifications as well?

It definitely needs something done in the client to auto-reconnect. The bare bones version above needs no changes to the server, but if you wanted something fancier, like having the cases of initial connect and auto reconnect handled/shown differently somehow, then the server might need to be modified.

Upvotes: 2

Related Questions