Fix #233: Refactor server logic for websockets and sync

This patch does a number of things, mostly aimed at being more careful about error states, and not causing, or avoiding, crashes.

A few things to note:
* I've moved away from `on('event')` to `onevent` so that I can safely manage a single listener at all times.  This makes it easier to reason about what is going to get triggered when.
* I've moved to always using `data.data` for `onmessage(data, flags)` since node also requires it.  We should confirm this works OK when the client is a browser.
* I've added more cases where we send back error SyncMessages to the client when things go wrong (e.g., invalid data)
* I've stopped using `socket.send` everywhere, and instead introduced `sync.sendMessage` which manages access to the ws instance, and makes sure we don't throw.  If we do, I emit an error so that we can deal with it (i.e., we shutdown the client cleanly now vs. crashing)
* I've added logic for dealing with the wss (server) erroring, where we now try to restart it, and if we can't, we bring down the server safely.
* I've added some new Sync states to reflect errors and the sync being terminated.
* I've streamlined a few users of `updateLastContact` since we were calling it multiple times in the same code path, which isn't necessary.

I've made various other code improvements as well, but the diff will show those better.  I spent a bunch of time reading https://github.com/einaros/ws/blob/master/lib/WebSocket.js and https://github.com/einaros/ws/blob/master/lib/WebSocketServer.js closely to make sure we are following what it actually does in terms of errors, states, events, etc.

A more descriptive answer to 1:
ws.close updates the ws readystate to CLOSING, then sends the 'closing' message to the client....then after that, it calls ws.terminate which cleans up resources and updates the readyState to CLOSED.
When we call terminate again, it bails as soon as it sees that the readyState is CLOSED