<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Abhinav Singh</title>
	<atom:link href="https://abhinavsingh.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://abhinavsingh.com</link>
	<description>Engineering, Music, Photography</description>
	<lastBuildDate>Fri, 25 Oct 2019 01:53:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0</generator>
<site xmlns="com-wordpress:feed-additions:1">84121904</site>	<item>
		<title>Proxy.py &#8211; A lightweight, single file HTTP proxy server in Python</title>
		<link>https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/</link>
					<comments>https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Fri, 12 Oct 2018 10:23:07 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[appurify]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/?p=1680</guid>

					<description><![CDATA[<p>In several cases, developers wanted their uploaded (unreleased) mobile apps to communicate with under-development server-side modules running within company intranet. In absence of a communication channel between Appurify devices and company intranet, developers were forced to either disable such features in their mobile apps or simply ignore testing such features. To facilitate end-to-end testing for such scenarios, I architected a proxy infrastructure; A stripped down version of which was a lightweight HTTP proxy server in Python.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/">Proxy.py &#8211; A lightweight, single file HTTP proxy server in Python</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Back in 2014, while working at <a href="https://techcrunch.com/2014/06/25/google-appurify/" target="_blank" rel="noopener noreferrer">Appurify Inc.</a> <em>(now <a href="https://firebase.google.com/docs/test-lab/" target="_blank" rel="noopener noreferrer">Firebase Test Lab</a>)</em> I came across a very interesting problem. To build some context, Appurify enabled mobile test automation on real devices for mobile teams to build better apps. Companies would upload their .apk <em>(Android app)</em> and .ipa <em>(iOS app)</em> files on Appurify servers and configure various test profiles <em>(Network, Memory, GPS etc conditions)</em> to perform wide-scale testing on Appurify mobile devices. This allowed developers to catch bugs and other performance issues on devices they can&#8217;t test themselves.</p>
<p>In several cases, developers wanted their uploaded <em>(unreleased)</em> mobile apps to communicate with under-development server-side modules running within company intranet. In absence of a communication channel between Appurify devices and company intranet, developers were forced to either disable such features in their mobile apps or simply ignore testing such features. To facilitate end-to-end testing for such scenarios, I architected a proxy infrastructure; A stripped down version of which was <a href="https://github.com/abhinavsingh/proxy.py" target="_blank" rel="noopener noreferrer">a lightweight HTTP proxy server in Python</a>.</p>
<p><a href="https://github.com/abhinavsingh/proxy.py"> </a><a href="https://github.com/abhinavsingh/proxy.py" target="_blank" rel="noopener noreferrer"><img class="alignnone" src="https://img.shields.io/github/forks/abhinavsingh/proxy.py.svg?style=social&amp;label=Fork" alt="" width="84" height="20" /></a><a href="https://github.com/abhinavsingh/proxy.py" target="_blank" rel="noopener noreferrer"><img loading="lazy" class="alignnone" src="https://img.shields.io/github/stars/abhinavsingh/proxy.py.svg?style=social&amp;label=Stars" alt="" width="90" height="20" /></a></p>
<h3>How it works</h3>
<figure id="attachment_1681" aria-describedby="caption-attachment-1681" style="width: 960px" class="wp-caption aligncenter"><a href="https://github.com/abhinavsingh/proxy.py" target="_blank" rel="noopener noreferrer"><img data-attachment-id="1681" data-permalink="https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/proxy-py-infrastructure/" data-orig-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?fit=960%2C720&amp;ssl=1" data-orig-size="960,720" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Proxy.py Infrastructure" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?fit=960%2C720&amp;ssl=1" loading="lazy" class="wp-image-1681 size-full" src="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?resize=960%2C720" alt="" width="960" height="720" srcset="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?w=960&amp;ssl=1 960w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2018/10/Proxy.py-Infrastructure.png?resize=768%2C576&amp;ssl=1 768w" sizes="(max-width: 960px) 100vw, 960px" data-recalc-dims="1" /></a><figcaption id="caption-attachment-1681" class="wp-caption-text">A simplified view of proxy infrastructure</figcaption></figure>
<p>A quick run through of the process:</p>
<ol>
<li>Developer builds and uploads mobile app on Appurify servers.</li>
<li>The developer also submits one or more test profile, enabling proxy infrastructure if necessary.</li>
<li>Prior to requesting proxy infrastructure, developers were expected to start Appurify provided proxy.py module within the company network <em>(more on it below)</em>.</li>
<li>If proxy infrastructure was enabled for a test, mobile app network traffic for that test would be routed through Appurify&#8217;s tunnel gateway <em>(using </em>iptables<em>).</em></li>
<li>Mobile traffic reaches the company internal network via the established tunnel.</li>
<li>Mobile traffic resolves within the company internal network using the HTTP proxy <em>(the open source part)</em> started as part of step 3.</li>
</ol>
<p>Above workflow allowed mobile developers to enable a test environment on Appurify devices, similar to how it would be if they tested their mobile apps on a locally handheld mobile device. Example:</p>
<ol>
<li>Mobile apps can now access unreleased server-side module, available only from within the company internal network</li>
<li>Mobile apps would experience external websites tailored for the region where the developer lived. Example, for a developer sitting in China, visiting <a href="https://www.google.com">google.com</a> on Appurify devices will redirect to <a href="http://www.google.cn">google.cn</a>.</li>
</ol>
<h3>Within the Proxy Module</h3>
<p>Shipped proxy module consisted of 2 parts:</p>
<ol>
<li>SSH Tunnel &#8212; It allowed bidirectional communication channel between Appurify mobile devices and company internal network. SSH tunnels were secured using public-private key infrastructure.</li>
<li>HTTP Proxy &#8212; It allowed incoming HTTP traffic from Appurify mobile devices to resolved within the context of a company internal network.</li>
</ol>
<p>Only the HTTP proxy piece was open sourced, a lightweight, single file module implementation of HTTP specification supporting HTTP, HTTPS, and even WebSocket requests proxy.</p>
<p>I had some real fun architecting, developing and solving this problem and it was a real pleasure listening from customers &#8220;Hey, this just magically works. Thank you!!!&#8221;.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/">Proxy.py &#8211; A lightweight, single file HTTP proxy server in Python</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1680</post-id>	</item>
		<item>
		<title>Customizing Redis pubsub for message persistence &#8211; Part 2</title>
		<link>https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence-part-2/</link>
					<comments>https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence-part-2/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Sat, 04 Apr 2015 04:08:30 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[PubSub]]></category>
		<category><![CDATA[Redis]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/?p=1574</guid>

					<description><![CDATA[<p>In the last post we saw how Redis can easily be modified to persist the last published message on PubSub channels. Without subscribing to the PubSub channel we were able to get the last published message from Redis db. In this post, I will take that idea one step ahead and add native capabilities within Redis to persist all the unprocessed messages published on PubSub channel in channel specific lists. We'll also preserve our capability to send the last published message to clients upon subscription.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence-part-2/">Customizing Redis pubsub for message persistence &#8211; Part 2</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a title="Redis" href="http://redis.io/" target="_blank" rel="noopener noreferrer"><img src="http://upload.wikimedia.org/wikipedia/en/thumb/6/6b/Redis_Logo.svg/467px-Redis_Logo.svg.png" alt="Redis Logo" /></a></p>
<p>In the <a title="Customizing Redis pubsub for message persistence" href="http://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence/" target="_blank" rel="noopener noreferrer">last post</a> we saw how Redis can easily be modified to persist the last published message on PubSub channels. Without subscribing to the PubSub channel we were able to get the last published message from Redis db. In this post, I will take that idea one step ahead and add native capabilities within Redis to persist all the unprocessed messages published on PubSub channel in channel specific lists. We&#8217;ll also preserve our capability to send the last published message to clients upon subscription.</p>
<h1>But why are we doing this?</h1>
<p>Popular open source application that provide support for Redis are based out of it&#8217;s list class of API. For example, let&#8217;s look at <a title="Celery: A distributed task queue" href="http://www.celeryproject.org/" target="_blank" rel="noopener noreferrer">Celery</a> which is a distributed task queue written in Python. Start <code>redis-cli MONITOR</code> on a terminal and then start celery in another window as follows:</p>
<pre class="c">$ pip install celery
$ celery worker --queues=testing --broker=redis:// --without-gossip --without-mingle --without-heartbeat
</pre>
<p>You&#8217;ll find celery polling Redis periodically as indicated by log lines like <code>"BRPOP" "testing" "testing\x06\x163" "testing\x06\x166" "testing\x06\x169" "1"</code>. Celery uses the Redis PubSub mechanism (that we disabled in the above command) only for internal features. <a title="Sentry: Exception logging and aggregation platform" href="https://getsentry.com/" target="_blank" rel="noopener noreferrer">Sentry</a>, a popular exception logging and aggregation library, internally depends upon Celery. There is an <a title="Redis pubsub for Celery" href="https://github.com/celery/celery/pull/2511" target="_blank" rel="noopener noreferrer">open pull request</a> that claims to add Redis pubsub based support to Celery. In the world of Ruby, background processing frameworks like <a title="Requeue job uses Redis rpoplpush" href="https://github.com/resque/resque/blob/master/lib/resque/job.rb#L139" target="_blank" rel="noopener noreferrer">Requeue</a> and <a title="Sidekiq" href="http://sidekiq.org/" target="_blank" rel="noopener noreferrer">Sidekiq</a> depend upon Redis list class of API&#8217;s.</p>
<p>However, with no native support for persistence of PubSub messages in Redis, it&#8217;s not difficult to understand why adopting to Redis PubSub can be tricky for some. Currently, Redis simply drops the message if no subscribers are found. Hence, question really is whether your application is tolerant to loss of published messages (for example, dropped messages while you were upgrading your application) ?</p>
<p>To solve persistence problem with Redis pubsub, the usual approach is to start multiple application instances. Some instances can continue to serve while others get deployed. However still, your active instances might be experiencing a network partition and unable to receive published messages. After all, primary goal is to guarantee processing of every message received by Redis irrespective of whether we are using list or pubsub based backend. A native support to solve persistence problems with Redis PubSub is clearly desirable.</p>
<h1>Persisting dropped Redis PubSub messages in a list</h1>
<p>In the last post we added a single line of code to persist the last published message on channels in a separate Redis key. We&#8217;ll update implementation to push every received message at the end of a channel specific list. Replace `setKey(c-&gt;db, c-&gt;argv[1], c-&gt;argv[2]);` line that we added the last time with following code:</p>
<pre class="c">// Persist messages in list only if no receivers were found
if (receivers == 0) {
    int j, pushed = 0, where = REDIS_TAIL;

    // Fetch list key from the database
    robj *lobj = lookupKeyWrite(c-&gt;db,c-&gt;argv[1]);

    // For every published message on the channel
    for (j = 2; j &lt; c-&gt;argc; j++) {
        c-&gt;argv[j] = tryObjectEncoding(c-&gt;argv[j]);

        // Ensure we have our quicklist initialized
        if (!lobj) {
            lobj = createQuicklistObject();
            quicklistSetOptions(lobj-&gt;ptr, server.list_max_ziplist_size,
                                server.list_compress_depth);
            dbAdd(c-&gt;db,c-&gt;argv[1],lobj);
        }

        // Push message at the tail of the list
        listTypePush(lobj,c-&gt;argv[j],where);
        pushed++;
    }

    // Signal key watchers and internal event subscribers
    if (pushed) {
        char *event = (where == REDIS_HEAD) ? "lpush" : "rpush";
        signalModifiedKey(c-&gt;db,c-&gt;argv[1]);
        notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c-&gt;argv[1],c-&gt;db-&gt;id);
    }
    server.dirty += pushed;
}</pre>
<p>I have added some comments in the code for clarity. This code is merely is a rip off of <code>src/t_list.c:pushGenericCommand</code> function. We don&#8217;t want to send replies to the client that are usually sent after an <code>RPUSH</code> command. Frankly, we can further refactor <code>pushGenericCommand</code> function to turn the above code into a single function call.</p>
<p><code>make test</code> and start <code>./src/redis-server</code>. Using <code>./src/redis-cli</code> try:</p>
<pre class="c">$ ./src/redis-cli 
127.0.0.1:6379&gt; publish persistent-channel this
(integer) 0
127.0.0.1:6379&gt; publish persistent-channel is
(integer) 0
127.0.0.1:6379&gt; publish persistent-channel gonna
(integer) 0
127.0.0.1:6379&gt; publish persistent-channel be
(integer) 0
127.0.0.1:6379&gt; publish persistent-channel awesome
(integer) 0
127.0.0.1:6379&gt; lrange persistent-channel 0 -1
1) "this"
2) "is"
3) "gonna"
4) "be"
5) "awesome"
127.0.0.1:6379&gt;</pre>
<p>Voila! Since we published a few messages with no active subscriber, they all got persisted in a list named after the channel itself. Now incoming subscribers can process pending messages by fetching them from the list which otherwise would have been dropped.</p>
<h1>Delivering unprocessed messages to subscribers upon subscription</h1>
<p>Instead of depending upon clients to poll for channel list length, server can deliver unprocessed messages to subscribers upon successful subscription. Since this can get overwhelming for subscribers if there are several pending messages waiting in the list, we may not want to do this at all and leave it up to the clients. Let&#8217;s preserve our feature from the last post i.e. to deliver the last published message to clients upon subscription.</p>
<p>Here we don&#8217;t want to remove the last published message from our persistent list. We simply wish to send it to the incoming subscribers. For example, imagine cases like user status, location and mood being published on separated channels. Here is a method that will give back the last element from the list without removing it (equivalent to <code>LRANGE key -1 -1</code>):</p>
<pre class="c">robj *llast(redisClient *c, robj *key) {
    listTypeEntry entry;
    robj *o, *value = NULL;
    long llen;

    // Fetch list object from db
    o = lookupKeyRead(c-&gt;db, key);

    // Ensure key contains a list
    if(o != NULL &amp;&amp; o-&gt;encoding == REDIS_ENCODING_QUICKLIST) {
        // Get list iterator for "lrange key -1 -1" use case
        llen = listTypeLength(o);
        listTypeIterator *iter = listTypeInitIterator(o, llen-1, REDIS_TAIL);

        // Fetch last item, prepare value
        listTypeNext(iter, &amp;entry);
        quicklistEntry *qe = &amp;entry.entry;
        if (qe-&gt;value) {
            value = createStringObject((char *)qe-&gt;value,
                                       qe-&gt;sz);
        } else {
            value = createStringObjectFromLongLong(qe-&gt;longval);
        }
        listTypeReleaseIterator(iter);
    }
    return value;
}</pre>
<p>We now need to replace our modifications within subscription handling methods from the last post. Note, callee must call <code>decrRefCount</code> on the returned <code>robj</code> to free up created string object after delivery. Kindly check this <a title="Add persistence support for undelivered PubSub messages." href="https://github.com/abhinavsingh/redis/commit/6fdfc98dddcc1cc5585e17be910730f370f21010" target="_blank" rel="noopener noreferrer">github commit</a> for all the changes since the last post. You can also checkout <a title="Abhinav Singh's Redis Fork" href="https://github.com/abhinavsingh/redis" target="_blank" rel="noopener noreferrer">my Redis fork</a> and directly play with the modified code.</p>
<h2>Conclusion</h2>
<p>We saw how easy it is to modify Redis for fun and profit. By adding native persistence capabilities, we offload our task of ensuring processing of every message received by Redis cluster. After all, none of the magical client side logics will ever be as reliable as native support. By the way, <a title="Redis 3.0.0 with native clustering support" href="https://groups.google.com/forum/#!msg/redis-db/dO0bFyD_THQ/Uoo2GjIx6qgJ" target="_blank" rel="noopener noreferrer">Redis 3.0.0</a> was released this week with native support for clustering, checkout while it&#8217;s hot.</p>
<p>Leave your comments and feedback.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence-part-2/">Customizing Redis pubsub for message persistence &#8211; Part 2</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence-part-2/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1574</post-id>	</item>
		<item>
		<title>Customizing Redis pubsub for message persistence</title>
		<link>https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence/</link>
					<comments>https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Mon, 30 Mar 2015 08:01:49 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Redis]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/?p=1537</guid>

					<description><![CDATA[<p>Redis comes packed with a simple yet powerful PubSub API.  It provides low latency and scales well.  A message published on a channel is received by subscriber(s) at the other end.  However, if no active subscriber is found the message is simply lost.  This drawback puts Redis out of the probables list for several use cases where message persistence of unprocessed published messages is desired.  It's also probably a reason why several open source projects that support Redis as a broker are based upon it's list push / pop API.  In this post I will demonstrate how to modify Redis PubSub API to support message persistence, opening possibilities for several interesting use cases.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence/">Customizing Redis pubsub for message persistence</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a title="Redis" href="http://redis.io/" target="_blank" rel="noopener noreferrer"><img src="http://upload.wikimedia.org/wikipedia/en/thumb/6/6b/Redis_Logo.svg/467px-Redis_Logo.svg.png" alt="Redis Logo" /></a></p>
<p>Redis comes packed with a simple yet powerful <a title="Redis Pubsub" href="http://redis.io/topics/pubsub" target="_blank" rel="noopener noreferrer">PubSub API</a>.  It provides low latency and scales well.  A message published on a channel is received by subscriber(s) at the other end.  However, if no active subscriber is found the message is simply lost.  This drawback puts Redis out of the probables list for several use cases where message persistence of unprocessed published messages is desired.  It&#8217;s also probably a reason why several open source projects that support Redis as a broker are based upon it&#8217;s list push / pop API.  In this post I will demonstrate how to modify Redis PubSub API to support message persistence, opening possibilities for several interesting use cases.</p>
<h1>Last Published Message</h1>
<p>Ability to fetch the last published message on a particular channel without subscribing to the channel opens doors for several interesting use cases.  <code>src/pubsub.c:publishCommand</code> is where Redis handles publish command.  Let&#8217;s add a line of code to persist the most recently published message on a channel:</p>
<pre class="c">void publishCommand(redisClient *c) {
    ....

    /* Persist last published message in channel specific key */
    setKey(c-&gt;db, c-&gt;argv[1], c-&gt;argv[2]);

    addReplyLongLong(....);
}
</pre>
<p>Above, we added a call to <code>src/db.c:setKey</code> function that sets the value of key <code>c-&gt;argv[1]</code> (channel name) to <code>c-&gt;argv[2]</code> (published message).</p>
<p>Run <code>make</code> from the project root directory and start <code>./src/redis-server</code>. Now we can do something like:</p>
<pre class="c">127.0.0.1:6379&gt; publish channel1 c1m1
(integer) 0
127.0.0.1:6379&gt; get channel1
"c1m1"
127.0.0.1:6379&gt; publish channel1 c1m2
(integer) 0
127.0.0.1:6379&gt; get channel1
"c1m2"
</pre>
<p>Voila. We published a message with no subscriber. However, an incoming user can still be served with the last published message on the channel by fetching the value of key <code>channel1</code> without explicitly subscribing to the channel.</p>
<p>Let&#8217;s take this idea one step ahead. XMPP Publish-Subscribe (<a title="XMPP Publish-Subscribe XEP-0060" href="http://www.xmpp.org/extensions/xep-0060.html#subscriber-subscribe-last" target="_blank" rel="noopener noreferrer">XEP-0060</a>) defines a specification for receiving the last published item. It says,</p>
<blockquote><p>When a subscription request is successfully processed, the service MAY send the last published item to the new subscriber.</p></blockquote>
<p>Let&#8217;s add this idea to Redis PubSub mechanism. <code>src/pubsub.c:subscribeCommand</code> function is where Redis processes channel subscription requests. Add the following lines of code at the end of this function.</p>
<pre class="c">void subscribeCommand(redisClient *c) {
    ....

    /* Send last received message on the subscribed channel(s) */
    robj *o;
    for (j = 1; j &lt; c-&gt;argc; j++) {
    	o = lookupKeyRead(c-&gt;db, c-&gt;argv[j]);
    	if(o != NULL) {
		addReply(c,shared.mbulkhdr[3]);
		addReply(c,shared.messagebulk);
		addReplyBulk(c,c-&gt;argv[j]);
		addReplyBulk(c,o);
    	}
    }
}</pre>
<p>Here, post subscription, we fetch and send the last published message for all channels that the client just subscribed to. <code>make</code> and restart ./src/redis-server. Now on a new <code>./src/redis-cli</code> terminal subscribe to <code>channel1</code>:</p>
<pre>127.0.0.1:6379&gt; subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "message"
2) "channel1"
3) "c1m2"</pre>
<p>Voila! Now Redis server will send the last published message upon subscription. But what about <code>PSUBSCRIBE</code> use case?</p>
<p><code>src/pubsub.c:psubscribeCommand</code> handles pattern based channel subscription logic. Add following lines of code at the end of this function:</p>
<pre>void psubscribeCommand(redisClient *c) {
    ....

    /* Send last received message on the channel(s) matching subscribed patterns */
    for (j = 1; j &lt; c-&gt;argc; j++) {
    	robj *pat = c-&gt;argv[j];
    	dictIterator *di = dictGetIterator(server.pubsub_channels);
    	dictEntry *de;
    	while((de = dictNext(di)) != NULL) {
		robj *cobj = dictGetKey(de);
		sds channel = cobj-&gt;ptr;
		if (stringmatchlen((char*)pat-&gt;ptr,
				sdslen(pat-&gt;ptr),
				(char*)channel,
				sdslen(channel), 0)) {
			robj *o = lookupKeyRead(c-&gt;db, cobj);
			if(o != NULL) {
	                addReply(c,shared.mbulkhdr[4]);
	                addReply(c,shared.pmessagebulk);
	                addReplyBulk(c,pat);
	                addReplyBulk(c,cobj);
	                addReplyBulk(c,o);
			}
		}
	}
	dictReleaseIterator(di);
    }
}</pre>
<p>Above, for every subscribed pattern, we iterate over active <code>server.pubsub_channels</code> and check if the active channel matches the subscription pattern. On match we fetch and send the last published message on the channel to the client.</p>
<p>With previous <code>redis-cli</code> subscribe terminal running, open a new terminal and try:</p>
<pre>127.0.0.1:6379&gt; psubscribe channel*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "channel*"
3) (integer) 1
1) "pmessage"
2) "channel*"
3) "channel1"
4) "c1m2"</pre>
<h1>Next</h1>
<p>You can checkout my <a title="Redis PubSub Persistence - Abhinav Singh" href="https://github.com/abhinavsingh/redis/tree/pubsub-persistence" target="_blank" rel="noopener noreferrer">Redis fork</a> and commits under <code>pubsub-persistence</code> branch. Enhancements described above can also be found on this <a title="Persist last published message on pubsub channels" href="https://github.com/abhinavsingh/redis/commit/9e546d3d408a98d61c9aeca68bbd4f7b56c8c968" target="_blank" rel="noopener noreferrer">github commit</a>.</p>
<p>Currently it is unclear what Antirez (Sanfilippo Salvatore) plans to do further with PubSub in Redis. It stands on a solid base and recent efforts are rightly put behind Redis cluster. However, I see some interesting enhancements that can be made to Redis PubSub mainline. In the next post I will take the current idea one step ahead and add persistence support for all or only unprocessed published messages in a Redis list (possibly with a cap or expiration on persisted messages).</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence/">Customizing Redis pubsub for message persistence</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/customizing-redis-pubsub-for-message-persistence/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1537</post-id>	</item>
		<item>
		<title>Back to blogging: What to expect</title>
		<link>https://abhinavsingh.com/back-to-blogging-what-to-expect/</link>
					<comments>https://abhinavsingh.com/back-to-blogging-what-to-expect/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Sat, 25 Oct 2014 16:34:24 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=1443</guid>

					<description><![CDATA[<p>I started this blog as a way to share my experiments and experiences while learning web development and computer science in general. In the first 2 years (between Apr'08 and Aug'10) I wrote as many as 100 blog posts. Quite a frenzy. Ever since, I only managed to write 5-6 posts in the following 4 years, about nearly 45 drafts which may now never get published. Good thing is that, I am back to blogging, which means a lot to share.		</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/back-to-blogging-what-to-expect/">Back to blogging: What to expect</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Hello Readers,</p>
<p>I started this blog as a way to share my experiments and experiences while learning web development and computer science in general. In the first 2 years (between Apr&#8217;08 and Aug&#8217;10) I wrote as many as 100 blog posts. Quite a frenzy. Ever since, I only managed to write 5-6 posts in the following 4 years, about nearly 45 drafts which may now never get published. Good thing is that, I am back to blogging, which means a lot to share.</p>
<p>Briefly, here is what (or what not) to expect in the future posts:</p>
<ol>
<li><strong><del>PHP</del></strong><del></del> &#8211; In past, <a title="PHP blog posts" href="http://abhinavsingh.com/blog/?s=php" target="_blank" rel="noopener noreferrer">PHP has dominated the content</a> on this blog. Mostly web demos, some quick hacks or some JAXL library examples. However, I am no longer working actively with PHP since &#8217;10 and probably never saw it after &#8217;12. Expect zero <del>PHP</del>.<br />
<hr />
</li>
<li><strong><del>JAXL</del></strong><del></del> &#8211; No more PHP essentially means no more <a title="Jaxl Github Organisation" href="https://github.com/jaxl/JAXL" target="_blank" rel="noopener noreferrer">JAXL</a> posts. In fact, I recently moved JAXL repository to it&#8217;s own <a title="Jaxl Github Organization" href="https://github.com/jaxl" target="_blank" rel="noopener noreferrer">Github organization</a> where other collaborators can maintain, improve and work on it without requiring my active involvement. This organization also contains <a title="BOSH (bidirectional stream over http) connection manager written on top of Erlang OTP " href="https://github.com/jaxl/ebosh" target="_blank" rel="noopener noreferrer">other</a> repositories that I managed to open source from my startup <a title="Jaxl Introductory Video" href="https://www.youtube.com/watch?v=9PaMP2vmGsc&amp;list=UUirjFMpmC-j9BPEtuwSbhgg" target="_blank" rel="noopener noreferrer">Jaxl</a>.<br />
<hr />
</li>
<li><strong>XMPP</strong> &#8211; Unfortunately, I am no longer in touch with progress on <a title="XMPP RFC's" href="http://xmpp.org/xmpp-protocols/rfcs/" target="_blank" rel="noopener noreferrer">XMPP specifications</a>. Specs has evolved a lot, to an extent that some developers have reported <a title="mod_message_carbon" href="https://github.com/abhinavsingh/mod_message_carbon" target="_blank" rel="noopener noreferrer">mod_message_carbon</a> no longer works as expected with new <a title="Ejabberd" href="https://www.ejabberd.im/" target="_blank" rel="noopener noreferrer">Ejabberd</a> server version (also, Message Carbon extension <a title="Message Carbon" href="http://xmpp.org/extensions/xep-0280.html" target="_blank" rel="noopener noreferrer">XEP-0280</a> has itself been deprecated). However, XMPP will always be my preferred choice whenever I need entire suite of user-to-user, group messaging, presence, contacts management, Jingle / SIP integration and other features baked into XMPP XEPs. For my everyday messaging needs, new technologies like <a title="ZeroMQ" href="http://zeromq.org/" target="_blank" rel="noopener noreferrer">ZeroMQ</a>, AMQP (<a title="RabbitMQ" href="http://www.rabbitmq.com/" target="_blank" rel="noopener noreferrer">RabbitMQ</a>), <a title="MQTT machine-to-machine / internet of things connectivity protocol" href="http://mqtt.org/" target="_blank" rel="noopener noreferrer">MQTT</a> or even <a title="Redis PubSub" href="http://redis.io/topics/pubsub" target="_blank" rel="noopener noreferrer">Redis PubSub</a> are more suitable.<br />
<hr />
</li>
<li><strong>Java</strong> &#8211; After some journey I am now finally working full-time with <a title="JavaSE 7 documentation" href="http://docs.oracle.com/javase/7/docs/" target="_blank" rel="noopener noreferrer">Java</a>. I still hate it but trying to adapt, learn and love it for at least what it&#8217;s worth for.<br />
<hr />
</li>
<li><strong>Python</strong> &#8211; Thanks to my stint with <a title="Appurify, Inc" href="http://appurify.com" target="_blank" rel="noopener noreferrer">Appurify</a>, I had a chance to work full-time with <a title="Python 2.7.x documentation" href="https://docs.python.org/2/" target="_blank" rel="noopener noreferrer">Python</a>. I even <a title="Websocket + PubSub based web framework built over Tornado, Redis, ZMQ, SockJS" href="https://github.com/abhinavsingh/tord" target="_blank" rel="noopener noreferrer">managed</a> <a title="Lightweight HTTP Proxy Server in Python" href="https://github.com/abhinavsingh/proxy.py" target="_blank" rel="noopener noreferrer">to</a> <a title="Tail multiple remote files on terminal window" href="https://github.com/abhinavsingh/remotail" target="_blank" rel="noopener noreferrer">work</a> <a title="SAML identity provider (idp) and service provider (sp) integration for Django applications " href="https://github.com/abhinavsingh/django-saml2" target="_blank" rel="noopener noreferrer">on</a> <a title="Run your task asynchronously, communicate and control them with ease" href="https://github.com/abhinavsingh/task.py" target="_blank" rel="noopener noreferrer">some</a> <a title="Appurify Tunnel" href="https://github.com/appurify/appurify-tunnel" target="_blank" rel="noopener noreferrer">interesting</a> <a title="Asynchronous PubSub in Python using Redis, ZMQ, Tornado" href="https://github.com/abhinavsingh/async_pubsub" target="_blank" rel="noopener noreferrer">open</a> <a title="Pool of SSH channels accessible via RESTful API and command line utility " href="https://github.com/abhinavsingh/sshpool" target="_blank" rel="noopener noreferrer">source</a> <a title="Generate TTL based self expiring crumbs / tokens" href="https://github.com/abhinavsingh/crumb.py" target="_blank" rel="noopener noreferrer">Python</a> <a title="This is an experiment/demonstration/exercise to create secure server/client communication model using Python" href="https://github.com/abhinavsingh/secure-messaging" target="_blank" rel="noopener noreferrer">projects</a>. Even though now it&#8217;s no longer my primary language, Python is always fun specially when one is in a hurry of getting things done.<br />
<hr />
</li>
<li><strong>Golang / Erlang</strong> &#8211; I met <a title="Golang Documentation" href="http://golang.org/doc/" target="_blank" rel="noopener noreferrer">Golang</a> a year back. I met Erlang while hacking Ejabberd, Riak etc for my startup Jaxl and immediately fell in love with it. Nowadays, I am in love with Golang. It&#8217;s simple and precise, has similar message passing semantics (buffered channels) as found in Erlang (mail boxes). I highly recommend digging into these languages and getting comfortable with message passing programming paradigm. They will change how you approach and think about your application structure. Expect lots of Golang and some Erlang.<br />
<hr />
</li>
<li><strong>Docker</strong> &#8211; Who is not into docker these days? If that&#8217;s not the case with you, leave this post right now and head over to <a title="Docker User Guide" href="https://docs.docker.com/userguide/" target="_blank" rel="noopener noreferrer">docker user guide</a>. That&#8217;s how important I find this piece of beauty (technology). Expect a lot about docker in my future posts.<br />
<hr />
</li>
<li><strong>Startups</strong> &#8211; A lot of startup fun has kept me busy since &#8217;10, some experiences and learnings are worth sharing.<br />
<hr />
</li>
<li><strong>Android</strong> &#8211; I have been working full-time with mobiles (both Android and iOS) since &#8217;12. Not much of application making but a lot of hacking with <a title="Adb Protocol" href="https://android.googlesource.com/platform/system/core/+/master/adb/protocol.txt" target="_blank" rel="noopener noreferrer">Adb protocol</a> and <a title="iOS libimobiledevice" href="http://www.libimobiledevice.org/" target="_blank" rel="noopener noreferrer">libimobiledevice</a>.<br />
<hr />
</li>
<li><strong>System designing</strong> &#8211; Luckily, I happened to experience a lot of end-to-end system and network designing. This domain is of great interest once you start to have fun with Racks, Subnet, Routes, Switches, Firewalls, DNS, Multi-cast and entire suite of technology under this umbrella.</li>
</ol>
<p>Will end this post with some interesting images from the past.</p>
<figure id="attachment_1450" aria-describedby="caption-attachment-1450" style="width: 2048px" class="wp-caption aligncenter"><a href="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg"><img data-attachment-id="1450" data-permalink="https://abhinavsingh.com/back-to-blogging-what-to-expect/iphone-screen-fsckd/" data-orig-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?fit=2048%2C1536&amp;ssl=1" data-orig-size="2048,1536" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="iphone-screen-fsckd" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?fit=1024%2C768&amp;ssl=1" loading="lazy" class="wp-image-1450 size-full" src="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?resize=1505%2C1129" alt="Fsck'd iPhone screen" width="1505" height="1129" srcset="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?w=2048&amp;ssl=1 2048w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/iphone-screen-fsckd.jpg?resize=1568%2C1176&amp;ssl=1 1568w" sizes="(max-width: 1505px) 100vw, 1505px" data-recalc-dims="1" /></a><figcaption id="caption-attachment-1450" class="wp-caption-text">Swollen iPhone screen due to high device temperature</figcaption></figure>
<figure id="attachment_1449" aria-describedby="caption-attachment-1449" style="width: 952px" class="wp-caption aligncenter"><a href="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg"><img data-attachment-id="1449" data-permalink="https://abhinavsingh.com/back-to-blogging-what-to-expect/server-2/" data-orig-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?fit=952%2C1270&amp;ssl=1" data-orig-size="952,1270" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="server" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?fit=225%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?fit=768%2C1024&amp;ssl=1" loading="lazy" class="wp-image-1449 size-full" src="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?resize=952%2C1270" alt="Rackframe" width="952" height="1270" srcset="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?w=952&amp;ssl=1 952w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?resize=225%2C300&amp;ssl=1 225w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2014/10/server1.jpg?resize=768%2C1024&amp;ssl=1 768w" sizes="(max-width: 952px) 100vw, 952px" data-recalc-dims="1" /></a><figcaption id="caption-attachment-1449" class="wp-caption-text">Setting up Racks</figcaption></figure>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/back-to-blogging-what-to-expect/">Back to blogging: What to expect</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/back-to-blogging-what-to-expect/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1443</post-id>	</item>
		<item>
		<title>How to perform X-FACEBOOK-PLATFORM and Google Talk X-OAUTH2 XMPP authentication with PHP Jaxl library</title>
		<link>https://abhinavsingh.com/how-to-perform-x-facebook-platform-and-google-talk-x-oauth2-xmpp-authentication-with-php-jaxl-library/</link>
					<comments>https://abhinavsingh.com/how-to-perform-x-facebook-platform-and-google-talk-x-oauth2-xmpp-authentication-with-php-jaxl-library/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Mon, 17 Sep 2012 22:12:18 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Gtalk]]></category>
		<category><![CDATA[X-FACEBOOK-PLATFORM]]></category>
		<category><![CDATA[X-OAUTH2]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=1355</guid>

					<description><![CDATA[<p>Ever since Jaxl library first introduced support for X-FACEBOOK-PLATFORM XMPP authentication mechanism, it has changed significantly. Also, Google Talk now supports OAuth 2.0 Authorization, an XMPP extension to allow users to log in using OAuth 2.0 credentials. Both these mechanisms are a big win for XMPP developers, since real-time conversation experience can now be provided to their application users without asking them for their passwords. In this blog post, I will demonstrate how to perform X-FACEBOOK-PLATFORM and X-OAUTH2 XMPP authentication mechanism using Jaxl v3.x PHP Library.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/how-to-perform-x-facebook-platform-and-google-talk-x-oauth2-xmpp-authentication-with-php-jaxl-library/">How to perform X-FACEBOOK-PLATFORM and Google Talk X-OAUTH2 XMPP authentication with PHP Jaxl library</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Ever since Jaxl library <a href="http://abhinavsingh.com/blog/2010/08/facebook-chat-connect-with-x-facebook-platform-using-jaxl-2-0/">first introduced</a> support for <a href="https://developers.facebook.com/docs/chat/#platauth">X-FACEBOOK-PLATFORM</a> XMPP authentication mechanism, it has changed significantly. Also, Google Talk now supports <a href="https://developers.google.com/talk/jep_extensions/oauth">OAuth 2.0 Authorization</a>, an XMPP extension to allow users to log in using OAuth 2.0 credentials.</p>
<p>Both these mechanisms are a big win for XMPP developers, since real-time conversation experience can now be provided to their application users without asking them for their passwords. In this blog post, I will demonstrate how to perform X-FACEBOOK-PLATFORM and X-OAUTH2 XMPP authentication mechanism using <a href="http://abhinavsingh.com/blog/2012/09/working-with-jaxl-a-networking-library-in-php-part-1-an-introduction-philosophy-and-history/">Jaxl v3.x</a> PHP Library.</p>
<p><strong style="font-size: 18px;"><u>X-FACEBOOK-PLATFORM XMPP Authentication</u></strong><br />
Here is a quick guide on how to perform X-FACEBOOK-PLATFORM XMPP authentication using <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/xfacebook_platform_client.php">xfacebook_platform_client.php</a> which comes bundled with <a href="http://jaxl.readthedocs.org/en/latest/index.html">Jaxl</a> <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x">v3.x</a> <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/examples">examples</a>:</p>
<ul>
<li>Visit <a href="https://developers.facebook.com/apps">Facebook Developer Apps</a> page and register your application</li>
<li>Once registered, visit <a href="https://developers.facebook.com/tools/access_token/">access token tool</a> to get required parameters to perform X-FACEBOOK-PLATFORM authentication <a href="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png"><img data-attachment-id="1363" data-permalink="https://abhinavsingh.com/how-to-perform-x-facebook-platform-and-google-talk-x-oauth2-xmpp-authentication-with-php-jaxl-library/screen-shot-2012-09-18-blurred/" data-orig-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?fit=945%2C142&amp;ssl=1" data-orig-size="945,142" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Facebook Access Token Tool" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?fit=300%2C45&amp;ssl=1" data-large-file="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?fit=945%2C142&amp;ssl=1" loading="lazy" class="aligncenter size-full wp-image-1363" style="border: 1px solid #666;" title="Facebook Access Token Tool" src="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?resize=945%2C142" alt="Facebook Access Token Tool" width="945" height="142" srcset="https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?w=945&amp;ssl=1 945w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?resize=300%2C45&amp;ssl=1 300w, https://i0.wp.com/abhinavsingh.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-18-Blurred.png?resize=768%2C115&amp;ssl=1 768w" sizes="(max-width: 945px) 100vw, 945px" data-recalc-dims="1" /></a></li>
<li>Click on the debug button next to User Token and make sure xmpp_login is one of the extended permissions (scope)</li>
<li>Enter downloaded Jaxl library folder and run from command line as follows:<code>$ php examples/xfacebook_platform_client.php fb_user_id_or_username fb_app_key fb_access_token</code></li>
</ul>
<p>You can now take the source code of <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/xfacebook_platform_client.php">xfacebook_platform_client.php</a> and customize it for your application needs.</p>
<p><strong style="font-size: 18px;"><u>Google Talk X-OAUTH2 XMPP Authentication</u></strong><br />
Here is a quick guide on how to perform <a href="https://developers.google.com/talk/jep_extensions/oauth">Google Talk X-OAUTH2</a> XMPP authentication using <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/xoauth2_gtalk_client.php">xoauth2_gtalk_client.php</a> which comes bundled with <a href="http://jaxl.readthedocs.org/en/latest/index.html">Jaxl</a> <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x">v3.x</a> <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/examples">examples</a>:</p>
<ul>
<li>Visit <a href="https://developers.google.com/oauthplayground/">Google OAuth Playground</a> and input <code>https://www.googleapis.com/auth/googletalk</code> as the required scope. Press &#8220;Authorize API&#8221; and then &#8220;Allow Access&#8221; button on the redirected page</li>
<li>In step 2, simply press &#8220;Exchange authorize code for tokens&#8221; and copy the access token</li>
<li>Enter downloaded Jaxl library folder and run from command line as follows:<code>$ php examples/xoauth2_gtalk_client.php username@gmail.com access_token</code></li>
</ul>
<p>You can now take the source code of <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/xoauth2_gtalk_client.php">xoauth2_gtalk_client.php</a> and customize it for your application needs.</p>
<p>Wasn&#8217;t that simple <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/how-to-perform-x-facebook-platform-and-google-talk-x-oauth2-xmpp-authentication-with-php-jaxl-library/">How to perform X-FACEBOOK-PLATFORM and Google Talk X-OAUTH2 XMPP authentication with PHP Jaxl library</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/how-to-perform-x-facebook-platform-and-google-talk-x-oauth2-xmpp-authentication-with-php-jaxl-library/feed/</wfw:commentRss>
			<slash:comments>21</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1355</post-id>	</item>
		<item>
		<title>JAXLXml &#8211; Strophe style XML Builder : Working with Jaxl – A Networking Library in PHP – Part 2</title>
		<link>https://abhinavsingh.com/jaxlxml-strophe-style-xml-builder-working-with-jaxl-a-networking-library-in-php-part-2/</link>
					<comments>https://abhinavsingh.com/jaxlxml-strophe-style-xml-builder-working-with-jaxl-a-networking-library-in-php-part-2/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Wed, 12 Sep 2012 17:18:34 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[JAXL]]></category>
		<category><![CDATA[xml]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=1294</guid>

					<description><![CDATA[<p>Prior to Jaxl v3.x, the most ugliest piece of code inside Jaxl library was handling of XML packets. If you are working with XMPP protocol which is all about sending and receiving XML packets, it can become a nightmare if you don't have a proper XML manipulation library in your toolkit. For Jaxl v3.x, first thing I decided to write was JAXLXml class, which is a custom XML packet implementation with no external dependencies and is an extension over the ideas from Strophe.Builder class written by Jack Moffitt.  JAXLXml is generic enough to find a place inside any PHP application that requires easy and elegant XML packet creation. In this blog post, I will give an exhaustive overview of how to create XML packets using JAXLXml class.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/jaxlxml-strophe-style-xml-builder-working-with-jaxl-a-networking-library-in-php-part-2/">JAXLXml &#8211; Strophe style XML Builder : Working with Jaxl – A Networking Library in PHP – Part 2</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Prior to <a href="https://github.com/abhinavsingh/JAXL">Jaxl v3.x</a>, the most ugliest piece of code inside Jaxl library was handling of XML packets. If you are working with XMPP protocol which is all about sending and receiving XML packets, it can become a nightmare if you don&#8217;t have a proper XML manipulation library in your toolkit. For Jaxl v3.x, first thing I decided to write was <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/core/jaxl_xml.php">JAXLXml</a> class, which is a custom XML packet implementation with no external dependencies and is an extension over the ideas from <a href="http://strophe.im/strophejs/doc/1.0.2/files2/strophe-js.html#Strophe.Builder">Strophe.Builder</a> class written by <a href="http://metajack.im">Jack Moffitt</a>.</p>
<p><code>JAXLXml</code> is generic enough to find a place inside any PHP application that requires easy and elegant XML packet creation. In this blog post, I will give an exhaustive overview of how to create XML packets using JAXLXml class.</p>
<p><strong style="font-size: 18px;"><u>JAXLXml Constructor</u></strong><br />
Depending upon the need, there are several different ways of initializing a JAXLXml object:</p>
<ul>
<li><code>$xml_obj = new JAXLXml($name, $ns, $attrs, $text);</code></li>
<li><code>$xml_obj = new JAXLXml($name, $ns, $attrs);</code></li>
<li><code>$xml_obj = new JAXLXml($name, $ns, $text);</code></li>
<li><code>$xml_obj = new JAXLXml($name, $attrs, $text);</code></li>
<li><code>$xml_obj = new JAXLXml($name, $attrs);</code></li>
<li><code>$xml_obj = new JAXLXml($name, $ns);</code></li>
<li><code>$xml_obj = new JAXLXml($name);</code></li>
</ul>
<p>where:</p>
<ul>
<li><code>$name</code> &#8211; the XML node name</li>
<li><code>$ns</code> &#8211; the XML namespace</li>
<li><code>$attrs</code> &#8211; Key-Value (KV) pair of XML attributes</li>
<li><code>$text</code> &#8211; XML content</li>
</ul>
<p>Here are a few examples for each constructor style shown above:<br />
<!-- Missing Gist ID --></p>
<p>JAXLXml will sanitize attributes and text values as shown below:<br />
<!-- Missing Gist ID --></p>
<p><strong style="font-size: 18px;"><u>Manipulating Attributes, Child Nodes and Content</u></strong><br />
Below is an exhaustive list of methods available over initialized JAXLXml object <code>$xml_obj</code> for manipulating attributes, child nodes and content:</p>
<ul>
<li><code>c($name, $ns=null, $attrs=array(), $text=null)</code> : Append a child node at current rover and update the rover to point at newly added child node. Rover is nothing but a pointer indicating the level in the XML tree where this and other methods will perform. When an JAXLXml instance is initialized, rover points to the top level node. <!-- Missing Gist ID --></li>
<li><code>cnode($node)</code> : Append a child node given by <code>$node</code> (a JAXLXml object) at current rover and update the rover to point at newly added child node. <!-- Missing Gist ID --></li>
<li><code>t($text, $append=FALSE)</code> : Update text of the node pointed by current rover</li>
<li><code>top()</code> : Move rover back to the top in the XML tree</li>
<li><code>up()</code> : Move rover one step up the XML tree <!-- Missing Gist ID --></li>
<li><code>attrs($attrs)</code> : Merge new attributes specified as KV pair <code>$attrs</code> with existing attributes at the current rover.</li>
<li><code>match_attrs($attrs)</code> : Accepts a KV pair of attributes <code>$attrs</code>, return bool if all keys exist and have same value as specified in the passed KV pair.</li>
<li><code>exists($name, $ns=null, $attrs=array())</code> : Checks if a child with <code>$name</code> exist. If found, return matching child as JAXLXml object otherwise false. If multiple children exist with same name, this function will return on first matching child</li>
<li><code>update($name, $ns=null, $attrs=array(), $text=null)</code> : Update <code>$ns</code>, <code>$attrs</code> and <code>$text</code> (all at once) of an existing child node <code>$name</code></li>
<li><code>to_string($parent_ns=null)</code> : Return string representation of JAXLXml object</li>
</ul>
<p><strong style="font-size: 18px;"><u>Method Chaining</u></strong><br />
The best thing one will find while working with JAXLXml class is that all the above methods are chain-able i.e. Any complex XML structure can be built with a single line of code.</p>
<p>Here is an example building a fairly nested XML structure in a single line of code:<br />
<!-- Missing Gist ID --></p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/jaxlxml-strophe-style-xml-builder-working-with-jaxl-a-networking-library-in-php-part-2/">JAXLXml &#8211; Strophe style XML Builder : Working with Jaxl – A Networking Library in PHP – Part 2</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/jaxlxml-strophe-style-xml-builder-working-with-jaxl-a-networking-library-in-php-part-2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1294</post-id>	</item>
		<item>
		<title>Working with Jaxl &#8211; A Networking Library in PHP &#8211; Part 1 &#8211; An Introduction, Philosophy and History</title>
		<link>https://abhinavsingh.com/working-with-jaxl-a-networking-library-in-php-part-1-an-introduction-philosophy-and-history/</link>
					<comments>https://abhinavsingh.com/working-with-jaxl-a-networking-library-in-php-part-1-an-introduction-philosophy-and-history/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Sat, 08 Sep 2012 09:59:26 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Asynchronous]]></category>
		<category><![CDATA[JAXL]]></category>
		<category><![CDATA[Non-Blocking]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=1264</guid>

					<description><![CDATA[<p>Development of Jaxl library started way back in December'07 while I was working on a self-initiated project called Gtalkbots. The project is now dead, if you are interested in knowing more about it go through Gtalkbots BlogSpot. Jaxl v1.x was first released in Jan'09 and about a year later in Aug'10 Jaxl v2.x was released. First two versions were released as JAbber XMPP Library for writing clients and external server components.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/working-with-jaxl-a-networking-library-in-php-part-1-an-introduction-philosophy-and-history/">Working with Jaxl &#8211; A Networking Library in PHP &#8211; Part 1 &#8211; An Introduction, Philosophy and History</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Development of Jaxl library started way back in December&#8217;07 while I was working on a self-initiated project called <a href="http://gtalkbots.blogspot.in/">Gtalkbots</a>. The project is now dead, if you are interested in knowing more about it go through <a href="http://gtalkbots.blogspot.in/">Gtalkbots BlogSpot</a>. Jaxl <a href="http://code.google.com/p/jaxl/source/browse/">v1.x</a> was first released in Jan&#8217;09 and about a year later in Aug&#8217;10 Jaxl <a href="https://github.com/abhinavsingh/JAXL/tree/master">v2.x</a> was released. First two versions were released as <strong>JA</strong>bber <strong>X</strong>MPP <strong>L</strong>ibrary for writing clients and external server components.</p>
<p>While working on my startup <a href="https://angel.co/jaxl">Jaxl &#8211; A Platform As A Service (PAAS) for developing real-time applications</a>, I started experiencing v2.x limitations when my external server side components were unable to process XMPP packets at the speed they were sent by ejabberd server. I started restructuring and refactoring the library which gave birth to Jaxl <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x">v3.x</a>. Since v3.x was initially being used for developing the entire infrastructure, it shaped up as a networking library in PHP with stable support for XMPP protocol. However, later I had to rewrite several infrastructure components in <a href="www.erlang.org">Erlang Programming Language</a> due to several issues that PHP as a language couldn&#8217;t solve (after all PHP wasn&#8217;t made for such tasks). Finally in April&#8217;12, Jaxl v3.x was open sourced.</p>
<p>Jaxl v3.x is an asynchronous, non-blocking, event based networking library in PHP for writing custom TCP/IP client and server implementations. From previous versions, Jaxl library inherits a full blown stable support for XMPP protocol stack. In v3.0, support for HTTP protocol stack was also introduced. At the heart of every protocol stack sits a <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/core">Core stack</a>. It contains all the building blocks for everything that we aim to do with Jaxl library. Both <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/xmpp">XMPP</a> and <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/http">HTTP</a> protocol stacks are written on top of the <a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/core">Core stack</a>. Infact the source code of these protocol implementations knows nothing about the standard (inbuilt) PHP <a href="http://php.net/manual/en/book.sockets.php">socket</a> and <a href="http://php.net/manual/en/book.stream.php">stream</a> methods.</p>
<p><strong style="font-size: 18px;"><u>Philosophy</u></strong><br />
Jaxl is designed to work asynchronously in a non-blocking fashion and provides an event based callback API. Now what does all that mean?</p>
<p>By <strong>non-blocking</strong> and <strong>asynchronous</strong> it means, when a library function like:<br />
<code>$jaxl-&gt;send($stanza);</code> is called, it will return immediately i.e. this function call will NOT block any further execution of your application script until <code>$stanza</code> has actually been sent over the connected TCP socket. Infact, when this function is called, passed <code>$stanza</code> object is put into an output buffer queue, which will be flushed as and when underlying TCP socket is available for writes. Similarly, most of the <a href="http://jaxl.readthedocs.org/en/latest/users/jaxl_instance.html#available-methods">available methods</a> (wherever required and possible) inside Jaxl library are non-blocking and asynchronous in nature.</p>
<p>By <strong>event based</strong> callback API it means, application code will need to register/add callbacks over necessary events as they occur inside Jaxl instance lifecycle. A list of available event callbacks with some explanation can be found <a href="http://jaxl.readthedocs.org/en/latest/users/jaxl_instance.html#available-event-callbacks">here</a>. For example, most of the XMPP applications will usually register a callback over <code>on_auth_success</code> event. As and when this event occurs inside Jaxl instance lifecycle, registered function will be callback&#8217;d with necessary parameters (if any).</p>
<p><strong style="font-size: 18px;"><u>Related Links</u></strong></p>
<ul>
<li>Read library <a href="http://jaxl.readthedocs.org/en/latest/index.html">documentation</a></li>
<li><a href="https://github.com/abhinavsingh/JAXL/downloads">Download</a> the latest and greatest source from GitHub.</li>
<li>Have any Question? Want to discuss? Need Help? Use <a href="https://groups.google.com/forum/#!forum/jaxl">Google Group/Forum</a>.</li>
<li>Found something missing or a bug in the source code? Kindly <a href="https://github.com/abhinavsingh/JAXL/issues">report an issue</a>.</li>
<li>Fixed a bug? Want to submit a patch? Want to improve documentation? Checkout <a href="https://github.com/abhinavsingh/JAXL">source code</a> and contribute to the library</li>
</ul>
<p><strong style="font-size: 18px;"><u>XMPP Application Examples</u></strong></p>
<ul>
<li>Echo bot <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/echo_bot.php">client</a></li>
<li>Echo bot <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/echo_component_bot.php">external component</a></li>
<li>Echo bot <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/echo_facebook_client.php">facebook chat client</a> (X-FACEBOOK-PLATFORM auth)</li>
<li>Echo <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/echo_bosh_bot.php">BOSH bot</a> (cli)</li>
<li><a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/muc_log_bot.php">MUC</a> log bot</li>
<li>PubSub Node <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/publisher.php">Publisher</a> and <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/subscriber.php">Subscriber</a></li>
<li><a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/register_user.php">Register</a> Jabber User</li>
</ul>
<p><strong style="font-size: 18px;"><u>HTTP Application Examples</u></strong></p>
<ul>
<li><a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/echo_http_server.php">HTTP Server</a></li>
<li><a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/http_rest_server.php">HTTP REST Server</a></li>
<li>HTTP <a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/xmpp_rest.php">REST Interface for XMPP</a> client/components daemons running in the background</li>
<li>Make an HTTP request (<a href="https://github.com/abhinavsingh/JAXL/blob/v3.x/examples/curl.php">CURL call using Jaxl</a>)</li>
</ul>
<p><strong style="font-size: 18px;"><u>Stay Tuned</u></strong><br />
In coming weeks, under this series of blog posts titled &#8220;Working with Jaxl &#8211; A Networking Library in PHP&#8221;, I will cover following major topics with sample code:</p>
<ul>
<li>Explanation of each Core stack class and how to use them</li>
<li>Design of each XMPP and HTTP stack class</li>
<li>XMPP over HTTP</li>
<li>XMPP File Transfer and Multimedia Sessions</li>
<li>Understanding and Using External Jabber Components</li>
<li>Asynchronous Job/Task Queues</li>
<li>Developing Concurrent and Parallel Systems</li>
</ul>
<p>If you have any specific topic that you would like me to be cover, kindly let me know via your comments here.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/working-with-jaxl-a-networking-library-in-php-part-1-an-introduction-philosophy-and-history/">Working with Jaxl &#8211; A Networking Library in PHP &#8211; Part 1 &#8211; An Introduction, Philosophy and History</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/working-with-jaxl-a-networking-library-in-php-part-1-an-introduction-philosophy-and-history/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1264</post-id>	</item>
		<item>
		<title>Announcing Jaxl v3.x &#8211; asynchronous, non-blocking I/O, event based PHP client/server library</title>
		<link>https://abhinavsingh.com/announcing-jaxl-v3-x-asynchronous-non-blocking-io-event-based-php-clientserver-library/</link>
					<comments>https://abhinavsingh.com/announcing-jaxl-v3-x-asynchronous-non-blocking-io-event-based-php-clientserver-library/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Fri, 27 Jul 2012 06:09:10 +0000</pubDate>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JAXL]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=1233</guid>

					<description><![CDATA[<p>Jaxl v3.x is a successor of v2.x (and is NOT backward compatible), carrying a lot of code from v2.x while throwing away the ugly parts. A lot of components have been re-written keeping in mind the feedback from the developer community over the last 4 years. Also Jaxl shares a few philosophies from my experience with erlang and python languages.  Jaxl is an asynchronous, non-blocking I/O, event based PHP library for writing custom TCP/IP client and server implementations. From it's previous versions, library inherits a full blown stable support for XMPP protocol stack. In v3.0, support for HTTP protocol stack was also added.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/announcing-jaxl-v3-x-asynchronous-non-blocking-io-event-based-php-clientserver-library/">Announcing Jaxl v3.x &#8211; asynchronous, non-blocking I/O, event based PHP client/server library</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="https://github.com/abhinavsingh/JAXL/">Jaxl v3.x</a> is a successor of <a href="https://github.com/abhinavsingh/JAXL/tree/master">v2.x</a> (and is NOT backward compatible), carrying a lot of code from v2.x while throwing away the ugly parts. A lot of components have been re-written keeping in mind the feedback from the developer community over the last 4 years. Also Jaxl shares a few philosophies from my experience with erlang and python languages.</p>
<p>Jaxl is an asynchronous, non-blocking I/O, event based PHP library for writing custom TCP/IP client and server implementations. From it&#8217;s previous versions, library inherits a full blown stable support for XMPP protocol stack. In v3.0, support for HTTP protocol stack was also added.</p>
<p>At the heart of every protocol stack sits a Core stack. It contains all the building blocks for everything that we aim to do with Jaxl library. Both XMPP and HTTP protocol stacks are written on top of the Core stack. Infact the source code of protocol implementations knows nothing about the standard (inbuilt) PHP socket and stream methods.</p>
<p><a href="https://github.com/abhinavsingh/JAXL/">Source code on GitHub</a></p>
<p><a href="https://github.com/abhinavsingh/JAXL/tree/v3.x/examples">Examples</a></p>
<p><a href="http://jaxl.readthedocs.org/">Documentation</a></p>
<p><a href="https://groups.google.com/forum/#!forum/jaxl">Group and Mailing List</a></p>
<p><a href="https://github.com/abhinavsingh/JAXL/issues/new">Create a bug/issue</a></p>
<p>Read <a href="https://groups.google.com/d/msg/jaxl/hjARH6oQEQo/vQ3RP5O5dLUJ">why v3.x was written</a> and what traffic it has served in the past.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/announcing-jaxl-v3-x-asynchronous-non-blocking-io-event-based-php-clientserver-library/">Announcing Jaxl v3.x &#8211; asynchronous, non-blocking I/O, event based PHP client/server library</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/announcing-jaxl-v3-x-asynchronous-non-blocking-io-event-based-php-clientserver-library/feed/</wfw:commentRss>
			<slash:comments>22</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1233</post-id>	</item>
		<item>
		<title>How to Write a Spelling Corrector in Erlang (ESpell)</title>
		<link>https://abhinavsingh.com/how-to-write-a-spelling-corrector-in-erlang/</link>
					<comments>https://abhinavsingh.com/how-to-write-a-spelling-corrector-in-erlang/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Mon, 27 Feb 2012 09:12:57 +0000</pubDate>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[listcomprehensions]]></category>
		<category><![CDATA[spellcorrector]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=1193</guid>

					<description><![CDATA[<p>Erlang is a beautiful programming language from Ericsson which i first came across while cutomizing authentication flow of ejabberd about 2 years back. Ever since then I have been using erlang for all my application backend needs including custom http server, custom bosh conn. manager, xmpp components and clients, ... Recently i have even started churning my application html pages via erlang using erlydtl (an Erlang implementation of the Django Template Language). Years ago, i gave a successful shot at implementing Peter Norvig's Spell Corrector in PHP. Last weekend i attempted the same "Spell Corrector" algorithm in about 45 lines of Erlang code.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/how-to-write-a-spelling-corrector-in-erlang/">How to Write a Spelling Corrector in Erlang (ESpell)</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="http://www.erlang.org/">Erlang</a> is a beautiful programming language from Ericsson which i first came across while cutomizing authentication flow of <a href="https://github.com/processone/ejabberd">ejabberd</a> about 2 years back. Ever since then I have been using erlang for all my application backend needs including custom http server, custom bosh conn. manager, xmpp components and clients, &#8230; Recently i have even started churning my application html pages via erlang using <a href="http://code.google.com/p/erlydtl/">erlydtl</a> (an Erlang implementation of the Django Template Language).</p>
<p><a href="http://abhinavsingh.com/blog/2008/05/my-interview-with-yahoo-inc-part-1/">Years ago</a>, i gave a successful shot at implementing <a href="http://norvig.com/spell-correct.html">Peter Norvig&#8217;s Spell Corrector</a> in PHP. Last weekend i attempted the same &#8220;Spell Corrector&#8221; algorithm in about 45 lines of Erlang code.</p>
<p><strong style="font-size: 16px;"><u>ESpell:</u></strong></p>
<p>Complete code file with comments and explaination can be found here:<br />
<a href="https://github.com/abhinavsingh/espell">https://github.com/abhinavsingh/espell</a></p>
<pre class="php">-module(espell).
-define(alphabet, "abcdefghijklmnopqrstuvwxyz").
-export([start/0, correct/1]).

%%
%% API Functions
%%

%% @doc start spell checker
start() -&gt; train(words()).

%% @doc returns most probable correct candidate with score
correct(Word) -&gt;
	lists:foldl(
		fun(Candidate, {Correction, Score}) -&gt; 
			case ets:lookup(?MODULE, list_to_binary(Candidate)) of
				[{_, Counter}] when Counter &gt; Score -&gt; {Candidate, Counter};
				_ -&gt; {Correction, Score}
			end
		end, {Word, 0}, get_candidates(Word)).

%%
%% Local Functions
%%

words() -&gt;
	{ok, Bin} = file:read_file("../priv/big.txt"),
	{ok, Words} = regexp:split(binary_to_list(Bin), "[^a-zA-Z]"),
	lists:map(fun(X) -&gt; string:to_lower(X) end, Words).

train(Features) -&gt;
	io:fwrite("training initial word list...~n"),
	ets:new(?MODULE, [set, named_table]),
	lists:foreach(fun(X) -&gt;
		case ets:insert_new(?MODULE, {list_to_binary(X), 1}) of
			false -&gt; ets:update_counter(?MODULE, list_to_binary(X), 1);
			true -&gt; true
		end
	end, Features),
	io:fwrite("training complete...~n"),
	ok.

edits1(Word) -&gt;
	Splits = lists:foldl(fun(I, Acc) -&gt; Acc ++ [{string:substr(Word, 1, I), string:substr(Word, I+1, string:len(Word)-I)}] end, [{"", Word}], lists:seq(1, string:len(Word))),
	Deletes = [A ++ string:substr(B, 2) || {A,B} &lt;- Splits, B =/= []],
	Transposes = [A ++ string:substr(B, 2, 1) ++ string:substr(B, 1, 1) ++ string:substr(B, 3) || {A,B} &lt;- Splits, string:len(B) &gt; 1],
	Replaces = [A ++ binary_to_list(&lt;&gt;) ++ string:substr(B, 2) || {A,B} &lt;- Splits, B =/= [], C &lt;- ?alphabet],
	Inserts = [A ++ binary_to_list(&lt;&gt;) ++ B || {A,B} &lt;- Splits, C &lt;- ?alphabet],
	lists:usort(Deletes ++ Transposes ++ Replaces ++ Inserts).

%%edits2(Word) -&gt; lists:usort([E2 || E1 &lt;- edits1(Word), E2 &lt;- edits1(E1)]).
known_edits2(Word) -&gt; lists:usort([E2 || E1 &lt;- edits1(Word), E2 &lt;- edits1(E1), ets:member(?MODULE, list_to_binary(E2))]).
known(Words) -&gt; lists:usort([Word || Word &lt;- Words, ets:member(?MODULE, list_to_binary(Word))]).

get_candidates(Word) -&gt;
	C1 = known([Word]),
	if 
		length(C1) &gt; 0 -&gt; C1;
		true -&gt; C2 = known(edits1(Word)),
			if
				length(C2) &gt; 0 -&gt; C2;
				true -&gt;	C3 = known_edits2(Word),
					if length(C3) &gt; 0 -&gt; C3; 
					true -&gt; [Word] end
			end
	end.
</pre>
<p><strong style="font-size: 16px;"><u>Try It Out:</u></strong><br />
espell provides 2 simple function for all it&#8217;s working:</p>
<ul>
<li>start() : start espell which initiates reading initial data and training phase</li>
<li>correct(Word) : this accepts 1 parameter, which is the word you want to correct. It returns a 2-tuple, where 1st element is the correct word and 2nd element is a score (which right now simply means number of times correct word was seen in training data set)</li>
</ul>
<pre class="php">$ cd espell
$ erlc -o ebin/ src/espell.erl
$ erl -pa ebin/
Erlang R14B03 (erts-5.8.4) [source] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.4  (abort with ^G)
1&gt; espell:start().
training initial word list...
training complete...
ok
2&gt; espell:correct("speling").
{"spelling",4}
5&gt; espell:correct("somthing").
{"something",683}
</pre>
<p>This code makes extensive use of <a href="http://www.erlang.org/doc/programming_examples/list_comprehensions.html">list comprehensions</a> in erlang, which is hugely responsible for cutting down espell code to just 45 lines of erlang.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/how-to-write-a-spelling-corrector-in-erlang/">How to Write a Spelling Corrector in Erlang (ESpell)</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/how-to-write-a-spelling-corrector-in-erlang/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1193</post-id>	</item>
		<item>
		<title>JAXL library &#8211; List of available hooks for various XMPP events</title>
		<link>https://abhinavsingh.com/jaxl-library-list-of-available-hooks-for-various-xmpp-events/</link>
					<comments>https://abhinavsingh.com/jaxl-library-list-of-available-hooks-for-various-xmpp-events/#comments</comments>
		
		<dc:creator><![CDATA[Abhinav Singh]]></dc:creator>
		<pubDate>Wed, 06 Apr 2011 22:16:57 +0000</pubDate>
				<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[JAXL]]></category>
		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=680</guid>

					<description><![CDATA[<p>Jaxl 2.x provides an event mechanism using which developers can register callbacks for various xmpp events inside their application code. This blog post will demonstrate how to register callbacks for required xmpp events and go through a list of all available hooks. Finally, we will discuss parameters that are passed to called back methods by Jaxl core.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/jaxl-library-list-of-available-hooks-for-various-xmpp-events/">JAXL library &#8211; List of available hooks for various XMPP events</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Jaxl 2.x provides an event mechanism using which developers can register callbacks for various xmpp events inside their application code. This blog post will demonstrate how to register callbacks for required xmpp events and go through a list of all available hooks. Finally, we will discuss parameters that are passed to called back methods by Jaxl core.</p>
<p><strong style="font-size: 18px;"><u>Registering callback on XMPP events</u></strong><br />
Applications can register callback for various XMPP events. Jaxl core will then callback application methods (with 2 parameters) every time associated XMPP event occurs. Shown below are some sample examples for registering callbacks.</p>
<p>When application callback&#8217;d method is a function:</p>
<pre class="php">function postAuth($payload, $jaxl) {

}
$jaxl-&gt;addPlugin('jaxl_post_auth', 'postAuth');
</pre>
<p>When application callback&#8217;d method is a public static method of a class:</p>
<pre class="php">class MyXMPPApp {
    public static function postAuth($payload, $jaxl) {

    }
}
$jaxl-&gt;addPlugin('jaxl_post_auth', array('MyXMPPApp', 'postAuth'));
</pre>
<p>When application callback&#8217;d method is a public method inside a class:</p>
<pre class="php">class MyXMPPApp {
    function postAuth($payload, $jaxl) {

    }
}
$MyXMPPApp = new MyXMPPApp();
$jaxl-&gt;addPlugin('jaxl_post_auth', array($MyXMPPApp, 'postAuth'));
</pre>
<p>In all the above examples <code>jaxl_post_auth</code> is one of the available hook for registering callbacks.</p>
<p><strong style="font-size: 18px;"><u>List of available hooks</u></strong><br />
Below is a complete list of available hooks in order of their occurrence within a Jaxl instance life cycle:</p>
<p>Hooks for events related to instance connection and authentication steps in various modes:</p>
<ul>
<li>jaxl_post_connect</li>
<li>jaxl_get_auth_mech</li>
<li>jaxl_get_facebook_key</li>
<li>jaxl_post_auth_failure</li>
<li>jaxl_post_auth</li>
<li>jaxl_post_handshake</li>
<li>jaxl_pre_shutdown</li>
<li>jaxl_post_disconnect</li>
<li>jaxl_get_empty_body</li>
</ul>
<p>Hooks for events related to XMPP stream and stanza&#8217;s:</p>
<ul>
<li>jaxl_get_stream_error</li>
<li>jaxl_get_presence</li>
<li>jaxl_get_message</li>
<li>jaxl_get_iq_get</li>
<li>jaxl_get_iq_set</li>
<li>jaxl_get_iq_error</li>
<li>jaxl_send_message</li>
<li>jaxl_send_presence</li>
</ul>
<p>Hooks for events related to reading/writing of XMPP packets and internal packet routing:</p>
<ul>
<li>jaxl_get_xml</li>
<li>jaxl_send_xml</li>
<li>jaxl_send_body</li>
<li>jaxl_pre_handler</li>
<li>jaxl_post_handler</li>
</ul>
<p><strong>TO-DO:</strong> Update when every hook is called inside your application life cycle and list of parameters passed for each callback. As of now you can <code>var_dump($payload);</code> inside your callback method.</p>
<p>The post <a rel="nofollow" href="https://abhinavsingh.com/jaxl-library-list-of-available-hooks-for-various-xmpp-events/">JAXL library &#8211; List of available hooks for various XMPP events</a> appeared first on <a rel="nofollow" href="https://abhinavsingh.com">Abhinav Singh</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://abhinavsingh.com/jaxl-library-list-of-available-hooks-for-various-xmpp-events/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">680</post-id>	</item>
	</channel>
</rss>
