protected void sendHeaders()
        {
            _headersUpdated  = false;
            _headersUpdateID = GetRandomMessageId("headersupdate-");
            var msg = new WebSocketRequestMessageJson(WebSocketMessageKind.RpcRequest);

            msg.ID      = _headersUpdateID;
            msg.Headers = new Dictionary <string, string>();
            if (_headers != null)
            {
                foreach (var key in _headers.Keys)
                {
                    msg.Headers.Add(key, _headers[key]);
                }
            }

            if (_auth != null)
            {
                msg.Headers.Add("Authorization", _auth.ToValue());
            }

            var serialized = _marshaller.Marshal(msg);

            _logger.Logf(LogLevel.Trace, "WebSocketTransport Updating headers:\n{0}", serialized);
            _ws.Send(serialized);
        }
        public virtual void Send <I, O>(string service, string method, I payload, ClientTransportCallback <O> callback, C ctx)
        {
            try {
                if (!Ready)
                {
                    throw new Exception("WebSocketTransport is not ready.");
                }

                var req = new WebSocketRequestMessageJson(WebSocketMessageKind.RpcRequest);
                req.ID      = GetRandomMessageId();
                req.Service = service;
                req.Method  = method;
                req.Data    = _marshaller.Marshal(payload);

                var record = new WSRequest();
                _requests.Add(req.ID, record);
                record.Timer   = new Timer();
                record.Success = msg => {
                    O data;
                    try {
                        data = _marshaller.Unmarshal <O>(msg.Data);
                    }
                    catch (Exception ex) {
                        callback.Failure(new TransportMarshallingException("Unexpected exception occured during unmarshalling.", ex));
                        return;
                    }
                    callback.Success(data);
                };

                record.Failure = (ex) => {
                    callback.Failure(new TransportException("Request failed. ", ex));
                };
                record.Timer.Interval = DefaultTimeoutInterval * 1000;
                record.Timer.Elapsed += (sender, e) => {
                    HandleRPCFailure(req.ID, new Exception("Request timed out."));
                };

                var serialized = _marshaller.Marshal(req);
                _logger.Logf(LogLevel.Trace, "WebSocketTransport: Outgoing message: \n{0}", serialized);

                _ws.SendAsync(serialized, success => {
                    if (success)
                    {
                        return;
                    }
                    HandleRPCFailure(req.ID, new Exception("Sending request failed."));
                });
                record.Timer.Start();
            }
            catch (Exception ex)
            {
                callback.Failure(
                    new TransportException("Unexpected exception occured during async request.", ex)
                    );
            }
        }
        protected void HandleBuzzer(WebSocketRequestMessageJson msg)
        {
            var res = new WebSocketResponseMessageJson(WebSocketMessageKind.BuzzerResponse);

            res.Ref = msg.ID;
            try
            {
                res.Data = _dispatcher.Dispatch(_context, msg.Service, msg.Method, msg.Data);
            } catch (Exception ex)
            {
                res.Kind = WebSocketMessageKind.BuzzerFailure;
                res.Data = ex.Message;
            }

            _ws.Send(_marshaller.Marshal(res));
        }