/** * _subscribe - Private Interface * * @param Dictionary<string, object> args * args is channel name and Procedure function callback and timetoken * @param Procedure function callback. * @param string timetoken. */ private void _subscribe(Dictionary<string, object> args) { clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY); string channel = args["channel"].ToString(); Procedure callback = (Procedure)args["callback"]; object timetoken = args["timestamp"]; // Begin Recusive Subscribe try { // Build URL List<string> url = new List<string>(); url.Add("subscribe"); url.Add(this.SUBSCRIBE_KEY); url.Add(channel); url.Add("0"); url.Add(timetoken.ToString()); // Wait for Message List<object> response = _request(url); // Update TimeToken if (response[1].ToString().Length > 0) timetoken = (object)response[1]; // Run user Callback and Reconnect if user permits. object message = ""; foreach (object msg in (object[])response[0]) { if (this.CIPHER_KEY.Length > 0) { if (msg.GetType() == typeof(string)) { message = pc.decrypt(msg.ToString()); } else if (msg.GetType() == typeof(object[])) { message = pc.decrypt((object[])msg); } else if (msg.GetType() == typeof(Dictionary<string, object>)) { Dictionary<string, object> dict = (Dictionary<string, object>)msg; message = pc.decrypt(dict); } } else { if (msg.GetType() == typeof(object[])) { object[] obj = (object[])msg; JArray jArr = new JArray(); for (int i = 0; i < obj.Count(); i++) { jArr.Add(obj[i]); } message = jArr; } else if (msg.GetType() == typeof(Dictionary<string, object>)) { JObject jobj = new JObject(); foreach (KeyValuePair<string, object> pair in (Dictionary<string, object>)msg) { jobj.Add(pair.Key, pair.Value.ToString()); } message = jobj; } else { message = msg; } } if (!callback(message)) return; } // Keep listening if Okay. args["channel"] = channel; args["callback"] = callback; args["timestamp"] = timetoken; this._subscribe(args); } catch { System.Threading.Thread.Sleep(1000); this._subscribe(args); } }
/** * Publish * * Send a message to a channel. * * @param Dictionary<string, object> args * args is string channel name and object message * @return List<object> info. */ public List<object> Publish(Dictionary<string, object> args) { string channel = args["channel"].ToString(); object message = args["message"]; JavaScriptSerializer serializer = new JavaScriptSerializer(); clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY); if (this.CIPHER_KEY.Length > 0) { if (message.GetType() == typeof(string)) { message = pc.encrypt(message.ToString()); } else if (message.GetType() == typeof(object[])) { message = pc.encrypt((object[])message); } else if (message.GetType() == typeof(Dictionary<string, object>)) { Dictionary<string, object> dict = (Dictionary<string, object>)message; message = pc.encrypt(dict); } } // Generate String to Sign string signature = "0"; if (this.SECRET_KEY.Length > 0) { StringBuilder string_to_sign = new StringBuilder(); string_to_sign .Append(this.PUBLISH_KEY) .Append('/') .Append(this.SUBSCRIBE_KEY) .Append('/') .Append(this.SECRET_KEY) .Append('/') .Append(channel) .Append('/') .Append(serializer.Serialize(message)); // Sign Message signature = getHMACSHA256(string_to_sign.ToString()); } // Build URL List<string> url = new List<string>(); url.Add("publish"); url.Add(this.PUBLISH_KEY); url.Add(this.SUBSCRIBE_KEY); url.Add(signature); url.Add(channel); url.Add("0"); url.Add(serializer.Serialize(message)); // Return JSONArray return _request(url); }
/** * _subscribe - Private Interface * * @param Dictionary<string, object> args * args is channel name and Procedure function callback and timetoken * */ private void _subscribe(Dictionary<string, object> args) { Procedure callback=null, connect_cb, disconnect_cb, reconnect_cb, error_cb; clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY); string channel = args["channel"].ToString(); object timetoken = args["timestamp"]; // Validate Arguments if (args["callback"] != null) { callback = (Procedure)args["callback"]; } else { Console.WriteLine("Invalid Callback."); } if(args.ContainsKey("connect_cb") && args["connect_cb"] != null) connect_cb = (Procedure)args["connect_cb"]; else connect_cb = new Procedure(doNothing); if (args.ContainsKey("disconnect_cb") && args["disconnect_cb"] != null) disconnect_cb = (Procedure)args["disconnect_cb"]; else disconnect_cb = new Procedure(doNothing); if (args.ContainsKey("reconnect_cb") && args["reconnect_cb"] != null) reconnect_cb = (Procedure)args["reconnect_cb"]; else reconnect_cb = new Procedure(doNothing); if (args.ContainsKey("error_cb") && args["error_cb"] != null) error_cb = (Procedure)args["error_cb"]; else error_cb = (Procedure)args["callback"]; if (channel == null || channel =="") { error_cb("Invalid Channel."); return; } // Ensure Single Connection if (subscriptions != null && subscriptions.Count > 0) { bool channel_exist = false; foreach (Channel_status cs in subscriptions) { if (cs.channel == channel) { channel_exist = true; break; } } if (!channel_exist) { Channel_status cs = new Channel_status(); cs.channel = channel; cs.connected = true; subscriptions.Add(cs); } else { error_cb("Already Connected"); return; } } else { // New Channel Channel_status cs = new Channel_status(); cs.channel = channel; cs.connected = true; subscriptions = new List<Channel_status>(); subscriptions.Add(cs); } bool is_reconnected = false; // Begin Recusive Subscribe while (true) { try { // Build URL List<string> url = new List<string>(); url.Add("subscribe"); url.Add(this.SUBSCRIBE_KEY); url.Add(channel); url.Add("0"); url.Add(timetoken.ToString()); // Stop Connection? bool is_disconnect = false; foreach (Channel_status cs in subscriptions) { if (cs.channel == channel) { if (!cs.connected) { disconnect_cb("Disconnected to channel : " + channel); is_disconnect = true; break; } } } if (is_disconnect) return; // Wait for Message List<object> response = _request(url); // Stop Connection? foreach (Channel_status cs in subscriptions) { if (cs.channel == channel) { if (!cs.connected) { disconnect_cb("Disconnected to channel : " + channel); is_disconnect = true; break; } } } if (is_disconnect) return; // Problem? if (response == null || response[1].ToString() == "0") { for (int i = 0; i < subscriptions.Count(); i++) { Channel_status cs = subscriptions[i]; if (cs.channel == channel) { subscriptions.RemoveAt(i); disconnect_cb("Disconnected to channel : " + channel); } } // Ensure Connected (Call Time Function) while (true) { string time_token = Time().ToString(); if (time_token == "0") { // Reconnect Callback reconnect_cb("Reconnecting to channel : " + channel); Thread.Sleep(5000); } else { is_reconnected = true; break; } } if (is_reconnected) { break; } } else { foreach (Channel_status cs in subscriptions) { if (cs.channel == channel) { // Connect Callback if (!cs.first) { cs.first = true; connect_cb("Connected to channel : " + channel); break; } } } } // Update TimeToken if (response[1].ToString().Length > 0) timetoken = (object)response[1]; // Run user Callback and Reconnect if user permits. object message = ""; foreach (object msg in (object[])response[0]) { if (this.CIPHER_KEY.Length > 0) { if (msg.GetType() == typeof(string)) { message = pc.decrypt(msg.ToString()); } else if (msg.GetType() == typeof(object[])) { message = pc.decrypt((object[])msg); } else if (msg.GetType() == typeof(Dictionary<string, object>)) { Dictionary<string, object> dict = (Dictionary<string, object>)msg; message = pc.decrypt(dict); } } else { if (msg.GetType() == typeof(object[])) { object[] obj = (object[])msg; JArray jArr = new JArray(); for (int i = 0; i < obj.Count(); i++) { jArr.Add(obj[i]); } message = jArr; } else if (msg.GetType() == typeof(Dictionary<string, object>)) { message = extractObject((Dictionary<string, object>)msg); } else { message = msg; } } if (!callback(message)) return; } } catch { System.Threading.Thread.Sleep(1000); } } if (is_reconnected) { // Reconnect Callback args["channel"] = channel; args["callback"] = callback; args["timestamp"] = timetoken; this._subscribe(args); } }
/** * History * * Load history from a channel. * * @param Dictionary<string, string> args * args is channel name and int limit history count response. * @return List<object> of history. */ public List<object> History(Dictionary<string, string> args) { string channel = args["channel"]; int limit = Convert.ToInt32(args["limit"]); List<string> url = new List<string>(); url.Add("history"); url.Add(this.SUBSCRIBE_KEY); url.Add(channel); url.Add("0"); url.Add(limit.ToString()); if (this.CIPHER_KEY.Length > 0) { clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY); return pc.decrypt(_request(url)); } else { List<object> objTop = _request(url); List<object> result = new List<object>(); foreach (object o in objTop) { if(o.GetType() == typeof(Dictionary<string,object>)) { JObject jobj = new JObject(); foreach (KeyValuePair<string, object> pair in (Dictionary<string, object>)o) { jobj.Add(pair.Key, pair.Value.ToString()); } result.Add(jobj); } else if (o.GetType() == typeof(object[])) { object[] obj = (object[])o; JArray jArr = new JArray(); for (int i = 0; i < obj.Count(); i++) { jArr.Add(obj[i]); } result.Add(jArr); } else { result.Add(o); } } return result; } }
/** * History * * Load history from a channel. * * @param Dictionary<string, string> args * args is channel name and int limit history count response. * @return List<object> of history. */ public List<object> History(Dictionary<string, string> args) { string channel = args["channel"]; int limit = Convert.ToInt32(args["limit"]); List<string> url = new List<string>(); url.Add("history"); url.Add(this.SUBSCRIBE_KEY); url.Add(channel); url.Add("0"); url.Add(limit.ToString()); if (this.CIPHER_KEY.Length > 0) { clsPubnubCrypto pc = new clsPubnubCrypto(this.CIPHER_KEY); return pc.decrypt(_request(url)); } else { return _request(url); } }