public static void Send(ApplicationConfig applicationConfig, Message message)
        {
            var templateRestUrl = "{0}://{1}.{2}.eventsockets.com/?applicationKey={3}&version=" + applicationConfig.Version;

            var envelopeString = message.Sign(applicationConfig).ToJson();

            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;
            Stream httpWebRequestStream = null;

            try
            {
                System.Net.ServicePointManager.Expect100Continue = false;

                var buffer = Encoding.UTF8.GetBytes(envelopeString);

                httpWebRequest = (HttpWebRequest)WebRequest.Create(String.Format(templateRestUrl, (!applicationConfig.Secure ? "http" : "https"), (!applicationConfig.Secure ? "api" : "apis"), applicationConfig.ClusterKey, applicationConfig.ApplicationKey));
                httpWebRequest.Method = "POST";
                httpWebRequest.ContentType = "application/json";
                httpWebRequest.ContentLength = buffer.Length;

                httpWebRequestStream = httpWebRequest.GetRequestStream();
                httpWebRequestStream.Write(buffer, 0, buffer.Length);
                httpWebRequestStream.Close();

                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            }
            finally
            {
                if (httpWebRequestStream != null)
                {
                    httpWebRequestStream.Dispose();
                }

                if (httpWebResponse != null)
                {
                    httpWebResponse.Close();
                }
            }
        }
        // In this authentication example everyone gets authenticated by default, in production mode you would verify the
        // user by a session cookie or any other method to identify the user to either accept or deny the connection.
        protected void Page_Load(object sender, EventArgs e)
        {
            // Fetch applicationKey and socketId
            var applicationKey = Request.QueryString["applicationKey"];
            var socketId = Request.QueryString["socketId"];

            // Construct a message for your authentication response
            var message = new Message();

            // Add current timestamp to the message (which is mandatory when signing envelope)
            message.MessageData.Add("auth.unixtime", Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString());

            // Construct a messageArg
            var messageArg = new MessageArg("server", "channel", "connection", "authenticate");

            // Append socket.id
            messageArg.EventData.Add("socket.id", socketId);

            // Append socket.uuid
            // In this example we echo the socket.id, normally you would pass your unique id for the current user, eg. primary key or username from your database
            messageArg.EventData.Add("socket.uuid", socketId);

            // Add messageArg to message
            message.MessageArgs.Add(messageArg);

            // Setup an ApplicationConfig using your own keys (defined in web.config)
            var applicationConfig = new ApplicationConfig(
                ConfigurationManager.AppSettings["ClusterKey"],
                ConfigurationManager.AppSettings["ApplicationKey"],
                ConfigurationManager.AppSettings["SignatureKey"],
                false
            );

            // To allow the request you need to send the correct http status code (any other code than 202 will automatically deny the request, even if the signed envelope is valid)
            Response.StatusCode = 202;

            // Write the signed JSON envelope to page output
            Response.Write(message.Sign(applicationConfig).ToJson());
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            // Get application key
            var applicationKey = Request.QueryString["applicationKey"];

            // Get HTTP POST stream containing the JSON envelope request
            var httpPostStream = new System.IO.StreamReader(Request.InputStream);

            // Deserialize envelope from HTTP POST stream
            var requestEnvelope = Envelope.FromJson(httpPostStream.ReadToEnd());

            // Deserialize message from envelope
            var requestMessage = Message.FromJson(requestEnvelope.Message);

            // Prepare a message to be sent in response
            var responseMessage = new Message();

            // Add current timestamp to the message (which is mandatory when signing envelope)
            responseMessage.MessageData.Add("auth.unixtime", Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString());

            // Iterate each subscription request
            foreach (var requestMessageArg in requestMessage.MessageArgs)
            {
                var socketId = requestMessageArg.EventData["socket.id"];
                var socketUUID = requestMessageArg.EventData["socket.uuid"];
                var channelPrefix = requestMessageArg.ChannelPrefix;
                var channelName = requestMessageArg.ChannelName;
                var eventPrefix = requestMessageArg.EventPrefix;
                var eventName = requestMessageArg.EventName;

                // Make sure that messageArg is a channel subscription request
                if (eventPrefix == "channel" && eventName == "subscribe")
                {
                    // Construct a messageArg
                    var responseMessageArg = new MessageArg(channelPrefix, channelName, eventPrefix, eventName);

                    // Append socketId, no need to send socket.uuid)
                    responseMessageArg.EventData.Add("socket.id", socketId);

                    // In this example any subscription requests are allowed (set to false or ignore adding key/value to deny)
                    responseMessageArg.EventData.Add("channel.subscription", "true");

                    switch (channelPrefix.ToLower())
                    {
                        case "public":

                            // Public channel subscriptions will never be sent out as channel subscription request do not need any authentication.
                            // If client subscribes to a public and private channel at the same time only the private channel request will be sent
                            // to the subscription endpoint

                        case "private":

                            // Allow subscriber to trigger events within the request channel (set to false or ignore adding key/value to deny)
                            responseMessageArg.EventData.Add("channel.trigger", "true");

                            break;

                        case "presence":

                            // Allow subscriber to trigger events within the requested channel (set to false or ignore adding key/value to deny)
                            responseMessageArg.EventData.Add("channel.trigger", "true");

                            // Describe the subscriber (socket.id is echoed in this example, in real life you might send a JSON object with username, email etc..)
                            responseMessageArg.EventData.Add("socket.data", socketId);

                            break;
                    }

                    // Add messageArg to response message
                    responseMessage.MessageArgs.Add(responseMessageArg);

                }

            }

            // Setup an ApplicationConfig using your own keys (defined in web.config)
            var applicationConfig = new ApplicationConfig(
                ConfigurationManager.AppSettings["ClusterKey"],
                ConfigurationManager.AppSettings["ApplicationKey"],
                ConfigurationManager.AppSettings["SignatureKey"],
                false
            );

            // Write the signed JSON envelope to the output stream with correct status code and content-type
            Response.StatusCode = 202;
            Response.AddHeader("Content-Type", "application/json");
            Response.Write(responseMessage.Sign(applicationConfig).ToJson());
            Response.End();
        }