<?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/"
	>

<channel>
	<title>Moritz Haarmann&#039;s Blog &#187; Add new tag</title>
	<atom:link href="http://momo.brauchtman.net/tag/add-new-tag/feed/" rel="self" type="application/rss+xml" />
	<link>http://momo.brauchtman.net</link>
	<description>random thoughts.</description>
	<lastBuildDate>Fri, 27 Jan 2012 15:54:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Zeroconf made easy: Bonjour for Java, Part 2, Client Implementation</title>
		<link>http://momo.brauchtman.net/2009/01/09/zeroconf-made-easy-bonjour-for-java-client-implementation/</link>
		<comments>http://momo.brauchtman.net/2009/01/09/zeroconf-made-easy-bonjour-for-java-client-implementation/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 08:04:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[simpleyeteffective]]></category>
		<category><![CDATA[useful]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://momo.brauchtman.net/?p=190</guid>
		<description><![CDATA[I&#8217;ve been writing about the server side implementation aspects of Bonjour for Java a while ago, and I promised to explain the client side, which is a bit more tricky. The reasons therefore is that it makes heavy use of &#8230; <a href="http://momo.brauchtman.net/2009/01/09/zeroconf-made-easy-bonjour-for-java-client-implementation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been writing about the<a href="http://momo.brauchtman.net/2008/12/zeroconf-made-easy-using-bonjour-for-java/"> server side implementation aspects of Bonjour for Java </a>a while ago, and I promised to explain the client side, which is a bit more tricky. The reasons therefore is that it makes heavy use of asynchronous callbacks, leaving you no other choice but to implement some interfaces and understand the way things work behind the curtain.<span id="more-190"></span></p>
<p>So what is the client&#8217;s task? In our example it is to find, that is discover, services and make them accessible to our application. Of course, it uses the same mDNSResponder facilites discussed previously. To mention it again, mDNSResponder is, from our point of view, the single instance taking care about all actions required to either register, discover or browse services. And caused by the way it works ( by &#8220;talking&#8221; to the other peers on your network ) it can&#8217;t provide instant answers to requests made, that&#8217;s why asynchronous callbacks are required.</p>
<p>We used that killerapp example, and I&#8217;m going to continue with that, though any other name can of course be used.</p>
<p>I assume you already imported the apple package and read about how to install it if you&#8217;re unable to compile your class file.</p>
<pre lang="JAVA">import com.apple.dnssd.*;</pre>
<p>Before actually starting to putting it all together, let&#8217;s have a look at two interfaces that are important for our work. The one is BrowseListener, which actually defines the callbacks to call when a service is either lost or found.</p>
<pre lang="JAVA">public void serviceFound(DNSSDService browser,
                         int flags,
                         int ifIndex,
                         java.lang.String serviceName,
                         java.lang.String regType,
                         java.lang.String domain)

public void serviceLost(DNSSDService browser,
                        int flags,
                        int ifIndex,
                        java.lang.String serviceName,
                        java.lang.String regType,
                        java.lang.String domain)</pre>
<p>The other interface which is used to provide our application with the data necessary to connect to a discovered service using standard Java Sockets, is ResolveListener. This interface defines only one callback, serviceResolved</p>
<pre lang="JAVA">public void serviceResolved(DNSSDService resolver,
                            int flags,
                            int ifIndex,
                            java.lang.String fullName,
                            java.lang.String hostName,
                            int port,
                            TXTRecord txtRecord)</pre>
<p>which is called whenever Bonjour was apple to resolve a service. Of course, because of the BaseListener interface, operationFailed must be implemented, too. Let&#8217;s do something useful now.</p>
<p>First of all, we have to enable Bonjour and tell it what to call in case it finds something. It&#8217;s best done by having a Class which handles all the discovery stuff. So whatever your class is, just implement the interface BrowseListener, as the ResolveListener callbacks will be implemented using anonymous classes later. For me, the skeleton looks like this:</p>
<pre lang="JAVA">public class Discover implements BrowseListener {
	// the constructor.
	public Discover(){

	}

	public void serviceLost(DNSSDService browser, int flags, int ifIndex,
				String serviceName, String regType, String domain) {
	}

	public void serviceFound(DNSSDService browser, int flags, int ifIndex,
				String serviceName, String regType, String domain) {
	}

        public void operationFailed(DNSSDService arg0, int arg1) {
		// this one is required by BaseListener, which is the parent of all other Listener Interfaces.
	}
}</pre>
<p>Now I&#8217;m going to initialise Bonjour&#8217;s browsing capabilities in the constructor. Take care, It throws an exception if something goes wrong. It&#8217;s up to you what to do with it.</p>
<pre lang="JAVA">	public Discover(){
		try {
			browser = DNSSD.browse("_killerapp._tcp", this);
		} catch (DNSSDException e) {
			// do something fancy here.
		}
	}</pre>
<p>The method browse requires two arguments, the name of the service you are browsing for, and the callback handler, which is the calling object in that case. Bonjour handles the rest for us, and either one of the methods serviceFound or serviceLost gets called accordingly.</p>
<p>Assuming you are lucky and Bonjour finds a service with that name, serviceFound will be called. To resolve the found service to an IP address and a port, you need to call DNSSD.resolve, a method with the following signature</p>
<pre lang="JAVA">public static DNSSDService resolve(int flags,
                                   int ifIndex,
                                   java.lang.String serviceName,
                                   java.lang.String regType,
                                   java.lang.String domain,
                                   ResolveListener listener)
                            throws DNSSDException</pre>
<p>It&#8217;s okay to fill 0 in flags, for further meaning just read the <a href="http://developer.apple.com/documentation/Java/Reference/DNSServiceDiscovery_JavaRef/index.html">Javadoc</a>. Because our serviceFound method is already called with most of the required arguments, it&#8217;s quite easy to implement the resolve process.</p>
<pre lang="JAVA">DNSSD.resolve(0, ifIndex, serviceName, regType, domain, new ResolveListener(){
				public void serviceResolved(DNSSDService resolver, int flags, int ifIndex,
				String fullname, String hostname, int port, TXTRecord txtRecord){
					InetAddress theAddress;
					try {
						theAddress = InetAddress.getByName(hostname);
					} catch (UnknownHostException e) {
						// ouch..
					}
				}

				public void operationFailed(DNSSDService arg0, int arg1) {
					// ouch, again!
				}
			});</pre>
<p>So what&#8217;s happening here is that we create an anonymous class to handle the callbacks, which should look familiar if you&#8217;ve been doing some AWT stuff. Once the resolve process was successful, the serviceResolved method is called, and we resolve the hostname given there to create an InetAddress object filled with all the information we want to know.</p>
<p>And yes, that&#8217;s it. The same applies for the serviceLost method, which has the same signature, and it&#8217;s up to you what to do with that address object from now on! Hope this helped you a bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://momo.brauchtman.net/2009/01/09/zeroconf-made-easy-bonjour-for-java-client-implementation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ikea tired of selling furniture, now selling RAM</title>
		<link>http://momo.brauchtman.net/2009/01/08/ikea-tired-of-selling-furniture-now-selling-ram/</link>
		<comments>http://momo.brauchtman.net/2009/01/08/ikea-tired-of-selling-furniture-now-selling-ram/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 13:25:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[useless]]></category>
		<category><![CDATA[Add new tag]]></category>

		<guid isPermaLink="false">http://momo.brauchtman.net/?p=178</guid>
		<description><![CDATA[  Of course, the form factor is yet to be supported by new cutting-edge ( and cutting-tree ) machines, yet the price ( 3x = 1€ ) and the robust design leaves competitors far behind.]]></description>
			<content:encoded><![CDATA[<p> </p>
<div id="attachment_179" class="wp-caption alignright" style="width: 251px"><a href="http://momo.brauchtman.net/wp-content/uploads/2009/01/cimg0456.jpg" rel="lightbox[178]" title="cimg0456"><img class="size-medium wp-image-179" title="cimg0456" src="http://momo.brauchtman.net/wp-content/uploads/2009/01/cimg0456-241x300.jpg" alt="ram." width="241" height="300" /></a><p class="wp-caption-text">ram.</p></div>
<p>Of course, the form factor is yet to be supported by new cutting-edge ( and cutting-tree ) machines, yet the price ( 3x = 1€ ) and the robust design leaves competitors far behind.</p>
]]></content:encoded>
			<wfw:commentRss>http://momo.brauchtman.net/2009/01/08/ikea-tired-of-selling-furniture-now-selling-ram/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Foodhacking</title>
		<link>http://momo.brauchtman.net/2009/01/05/foodhacking/</link>
		<comments>http://momo.brauchtman.net/2009/01/05/foodhacking/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 04:18:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[personal]]></category>
		<category><![CDATA[useless]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[cooking]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[improvingtheworld]]></category>
		<category><![CDATA[simpleyeteffective]]></category>

		<guid isPermaLink="false">http://momo.brauchtman.net/?p=151</guid>
		<description><![CDATA[Good morning.   I just realised why i like cooking that much. Because it&#8217;s hacking &#8211; in a way. My french roommate ( a cool guy btw ) is very good at that, and he impressed me by &#8211; bring &#8230; <a href="http://momo.brauchtman.net/2009/01/05/foodhacking/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Good morning.</p>
<p> </p>
<div id="attachment_152" class="wp-caption alignright" style="width: 310px"><a href="http://momo.brauchtman.net/wp-content/uploads/2009/01/cimg0442.jpg" rel="lightbox[151]" title="french fries"><img class="size-medium wp-image-152" title="french fries" src="http://momo.brauchtman.net/wp-content/uploads/2009/01/cimg0442-300x225.jpg" alt="French fries" width="300" height="225" /></a><p class="wp-caption-text">French fries</p></div>
<p>I just realised why i like cooking that much. Because it&#8217;s hacking &#8211; in a way. My french roommate ( a cool guy btw ) is very good at that, and he impressed me by &#8211; bring in the cliché &#8211; preparing french fries in a pan. </p>
<p>I&#8217;m curious. All the time, people affine towards computers and related stuff are considered to eat only instant food or microwave dishes. True? I don&#8217;t think so, many nerd-friends of mine tend to cook from time to time, not the worst stuff.</p>
<p>It may of course also be affected by the desire for quality. Programming and hacking is sometimes just motivated by the need to improve a situation or to simplify a workflow. Same for food, I guess.</p>
<p>Breakfast was tasty, by the way.</p>
]]></content:encoded>
			<wfw:commentRss>http://momo.brauchtman.net/2009/01/05/foodhacking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

