2. Januar 2011

OAuth for TwiX

I finally added OAuth to TwiX, the Twitter-XMPP gateway.

Since August 2010 Twitter requires OAuth for API access. This is extremely stupid for background daemons like TwiX which do not have a user interface and especially no browser based UI.

TwiX is my C# playground. So, I needed an OAuth library for C#. TwiX runs on mono and .NET. I am running my instance of TwiX on a Linux server. Luckily almost all .NET libraries run without modification on mono.

A quick research returned several OAuth libraries, some are for ASP.NET, which I do not use, because TwiX is a faceless server daemon, not a Web application. I zeroed in on Shannon Whitley's implementation which comes with a handy sample project.

This example project has
- an OAuth core implementation
- a Twitter OAuth adapter
- a sample desktop app with embedded browser
= cool thing

I used the 2 OAuth classes in TwiX and converted the sample desktop app into a Twitter OAuth token generator tool (see screen shot). 1 hour of work, thanks Shannon.

This is a general Twitter token generator. It is not just for TwiX. The OAuthTwitterDesktopTool generates a twitter token and token secret for every Twitter app, if you know the app's consumer key and consumer secret. The OAuthTwitterDesktopTool is part of the TwiX distribution.

You can find TwiX with OAuth and the token generator on the TwiX homepage.

_happy_authorizing()

1. Dezember 2010

Science Fiction Comes True

This looks like an image from a Science Fiction movie. But it is not. It is reality.

The image shows a real astronaut in a real space station and a real earth through real windows.

We see astronaut Tracy Caldwell Dyson inside the cupola of the ISS space station. The cupola has been installed during Space Shuttle mission STS-130 on 15 February 2010. It is the largest window ever deployed in space.

The Space Shuttle era comes to an end. It seems to the public, that not much progress has been made. But there actually is development. The cupola image is one indication. And more than 100 Space Shuttle missions result in unprecedented operational experience in space. Another sign for advance is the fact, that the Space Shuttle was not the only one. There are other "returnable" launch systems in active operation (X-37B) created by organisations with a budget, that is larger than NASA's.
_happy_spacing()

19. Oktober 2010

26. September 2010

A Website Chat made easy with XMPP and BOSH


A description of the live chat feature on http://avatar.lupuslabs.de/contact.html

10 years ago we spent weeks to develop a website chat. We implemented a chat server in C++, a PHP library, which talked to the chat server and JavaScript streaming in an iframe. Today it is much simpler.

Today we can use XMPP and BOSH and let the web page talk to my GTalk client, which runs all the time anyway.

Here is the shopping list of technologies:
These components do all the work. There is only some Javascript code and a little bit of plumbing required.

1. Set up ejabberd:

Download ejabberd from http://www.ejabberd.im/. The easiest way is to use the installer from http://www.process-one.net/en/ejabberd/downloads

For XMPP to work we need XMPP users. I prefer to run ejabberd with MySQL storage, because MySQL is the easiest way for me to add users and to manage the user list programatically. But the mnesia database also works.

Here is the config to use MySQL with ejabberd (to be added to ejabberd.cfg):
% {auth_method, internal}. % disabled
{auth_method, odbc}. % enabled
{odbc_server, {mysql, "localhost", "ejabberd", "mysql-user", "mysql-password"}}
Also I comment out XMPP in-band account registration, so that nobody creates users on my server:
{access, register, [{deny, all}]}.
This article explains how to create tables for ejabberd in the MySQL server: https://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver

2. Set up Apache as BOSH proxy:

Enable Apache modules "proxy" and "proxy_http". The debian way:
% a2enmod proxy
% a2enmod proxy_http
Add to the proxy configuration (Debian: proxy.conf)
ProxyPass /xmpp-httpbind http://127.0.0.1:5280/http-bind
ProxyPassReverse /xmpp-httpbind http://127.0.0.1:5280/http-bind
By default accessing the proxy is only allowed for localhost. Since Browers will access it, it needs to be accessible from anywhere. Add to the proxy configuration (Debian: proxy.conf)
Allow from all
ProxyRequests Off
3. Create an HTML file and start programming

Download Strophe and jQuery (or use the CDN version http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js). Add references to the HTML-head:
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src='strophe.min.js'></script>
4. Now comes the real fun: coding

We basically create a BOSH connection from Javascript to ejabberd through apache/mod_proxy:
var conn = new Strophe.Connection('/xmpp-httpbind');
Create an XMPP user in MySQL (I am using phpmyadmin) and connect with this user:
conn.connect('test@wolfspelz.de', 'secret', OnConnectionStatus);
The OnConnectionStatus function may look like:

function OnConnectionStatus(nStatus)
{
if (nStatus == Strophe.Status.CONNECTING) {
} else if (nStatus == Strophe.Status.CONNFAIL) {
} else if (nStatus == Strophe.Status.DISCONNECTING) {
} else if (nStatus == Strophe.Status.DISCONNECTED) {
} else if (nStatus == Strophe.Status.CONNECTED) {
OnConnected();
}
}
When the connection is established, register message handlers and send our own presence:
function OnConnected()
{
conn.addHandler(OnPresenceStanza, null, "presence");
conn.addHandler(OnMessageStanza, null, "message");
conn.send($pres());
}
BTW: handlers should always return "true". Otherwise they are removed from the handler list. A message handler may look like:
function OnMessageStanza(stanza)
{
var sFrom = $(stanza).attr('from');
var sType = $(stanza).attr('type');
var sBareJid = Strophe.getBareJidFromJid(sFrom);
var sBody = $(stanza).find('body').text();
// do something, e.g. show sBody with jQuery
return true;
}
A presence handler may be:
function OnPresenceStanza(stanza)
{
var sFrom = $(stanza).attr('from');
var sBareJid = Strophe.getBareJidFromJid(sFrom);
var sType = $(stanza).attr('type');
var sShow = $(stanza).find('show').text();
// do something, e.g. show status icon with jQuery
return true;
}
The connection should be closed when the page unloads. Unfortunately strophe.js (at least up to version 1.0.2) disconnects asynchronously, which does not work when the page is destroyed. After some time the XMPP server will notice, that the page disappeared and will close the connection. But if you do not want to wait, then we have to force strophe to close immediately.

There is a patch, which allows for synchronous connection closing. The patch must be applied to the strophe.js file:
diff --git a/src/core.js b/src/core.js
index 5aeb06a..f79ae29 100644
--- a/src/core.js
+++ b/src/core.js
@@ -2161,7 +2161,8 @@ Strophe.Connection.prototype = {

             req.date = new Date();
             try {
-                req.xhr.open("POST", this.service, true);
+               var async = !('sync' in this && this.sync === true);
+                req.xhr.open("POST", this.service, async);
             } catch (e2) {
                 Strophe.error("XHR open failed.");
                 if (!this.connected) {
How to use the patch:
    this.conn.flush();
    this.conn.sync = true; // Set sync flag before calling disconnect()
    this.conn.disconnect();

5. Summary

Of course, all these functions and callbacks should be prototype based and bind the instance to the closure. We should also use a model-view architecture and handle the protocol stuff in the model, while notifying the view of really important events.

Here are the files:
contact.html - the "driver" which loads everything and produces the GUI
model.js - the model does it, classes: Model, Room, Participant
view.js - the view shows it, the view registers listeners with the model
utils.js - utility classes, logging, unit test, oberver pattern
config.js - configurations for test and production
setup.js - selects the appropriate configuration
style.css
lib/strophe.js - including the above patch
lib/jquery-1.4.2.min.js
lib/jquery-ui-1.8.5.custom.min.js
_happy_chatting()

11. September 2010

Service URLs should be Immutable

Service URLs are URLs where you (the client) expect a service. No surprise. Examples:

  • the URL of a SOAP WSDL is a service URL,
  • the REST URL of the Twitter timeline API: http://twitter.com/statuses/friends_timeline.xml,
  • name or URL of AJAX scripts of a web site,
  • a chat room URL provides a software bus service.
These service URLs are provided to the client. Usually they are configured. The client gets them somehow. The client uses them to access the service. BUT the client should never construct them or append to them or change them. Service URLs should be final.

Why? I don't know, but I feel, that it is a bad thing. I had several cases in real applications where constructing, appending to, manipulating service URLs made an application less extensible, more complex, less testable.

Extensibility: if the client constructs the service URL from parts, then future server changes must take the client URL construction into account. The server can not just supply a different service URL, because the client also does something and might prevent the server from changing the service URL stucture or the URL altogether. For example, if the client appends the path of a URL to a host name and if the client assumes, that the server language is PHP, then the service URL might always look like a PHP script, even if the server technology changes. Imagine the unfortunate sysadmin who has to configure a Java application server to serve ".php" URLs. The client will have to be changed when the server changes. This is bad.

Complexity: Constructing URLs in the client is more processing than doing nothing. It introduces IFs, methods, more constants. This is usually not a big issue, but it rare cases the additional complexity can be quite significant. I have seen these cases.

Testability: Service URLs point to resources. Resources are dependencies. A very important concept of unit testing is inversion of control by dependency injection. But if the client generates its dependencies, then inversion of control is more difficult, if not impossible. It is much better to let the server be in control by configuring the client for production and test cases.

Do not...
  • combine host name and path to URLs
  • append or decide on filename extensions
  • append query parameters
  • decide the protocol
  • insert or remove port numbers
...in the client. Just leave it as you get it. The server knows what's good for you.

Exceptions: however, you may...
  • decide the protocol (http vs. https) in AJAX clients for JS security reasons,
  • replace query arguments by treating the service URL as a template,
  • append URL parameters if (and only if) the service protocol consists of URL parameters (thanks Allan)
  • (any other exceptions?)
happy_webservicing()

16. August 2010

Stellenausschreibung Softwareentwickler/in

In den nächsten 12 Monaten bauen wir eine interne Entwicklung mit 2 Scrum Teams auf. Wir suchen besondere, gute Leute, die mit anpacken, Produkte und Projekte umsetzen und mit dem Unternehmen wachsen wollen. Wir haben hier die Chance eine moderne IT aufzubauen, moderner, als unser Top-Management für möglich hält. Alles ist neu, keine Altlasten. Neuer guter Code und Softwarearchitektur. Wer mich kennt, weiss, dass wir aktuelle Technologien verwenden: Agile, Scrum, Unittesting, Clean Code, SOLID, DRY,KISS und wir werden bald wieder ein regelmäßiges Developer-Seminar machen.

Ihre Aufgaben:
  • Selbständige Projektarbeit in einem Scrum- Team
  • Objektorientierte Analyse und Entwurf
  • Entwicklung von webbasierten Anwendungen und Webservices
  • Aktive Teilnahme an modernen agilen Entwicklungsprozessen
Ihre Skills:
  • Erfahrungen im Bereich objektorientierter Entwicklungsmethoden
  • Sehr gute Programmierkenntnisse in einer der Sprachen Java oder C++ oder C# oder PHP. Gute Programmierkenntnisse in einer der anderen Sprachen
  • Sicherer Umgang mit CSS, JavaScript, XML, DOM/DHTML, Subversion, Webservices, MySQL und Entwicklungsumgebungen
  • Kenntnisse agiler Entwicklungsmethoden wie Scrum und Unit-Testing
  • Idealerweise Erfahrung mit moderner Programmiermethodik wie TDD, SOLID, DRY, KISS
  • Abgeschlossenes Hochschulstudium der Informatik, Naturwissenschaften, Ingenieurwissenschaften oder vergleichbare Qualifikation mit mindestens einjähriger Berufserfahrung
  • Sehr gute Deutsch- und gute Englischkenntnisse.
Die Deutsche Messe stellt im B2B-Umfeld Kontakt zwischen Herstellern und Interessenten her. Dazu dienen die großen Präsenzmessen CeBIT, HANNOVER MESSE und viele andere. Die Deutsche Messe Interactive, eine Tochter der Deutschen Messe setzt das Business der Messe im Netz fort. Die DMI führt Anbieter und Geschäftskunden über das Internet zusammen. Durch enge Verzahnung mit den Marketing- und Vertriebssystemen der Hersteller wird der Wert solcher Kontakte wirtschaftlich messbar. Kein Spam, keine New Economy, keine Handelsplattform, sondern echte Business Leads.

Arbeitsort: Hannover oder Hamburg
Beginn: je früher desto besser
Sicherheit: ja, das Startup ist solide finanziert (kein VC)

Schreibt mir an: heiner.wolf@messe-interactive.de
Schickt mir eine Telefonnummer und ein kurzes Profil. Ich rufe zurück.

15. August 2010

Entwickler Kennenlernen

Bei Startups ist das Team meistens klein. Da hängt der Erfolg des Unternehmens von jedem Einzelnen ab. Deshalb versuchen wir immer wieder ein starkes Team zusammen zu stellen, das alle Entwicklungsherausforderungen meistern kann.


Am Anfang ist es sehr schwer Entwickler/innen einzuschätzen. Der eine behauptet, eine Programmiersprache zu kennen, hat sie aber nur in der Vorlesung gesehen. Die andere gibt an "nur so ein bisschen zu programmieren", aber nicht richtig. Später kommt heraus, dass sie die Benutzerverwaltung für das Wohnheim als Webanwendung nebenbei gemacht hat und auch noch eine iPhone App dafür.

Und dann gibt es noch so viele Technologien. Keiner kann alles abdecken. Es ist fast unverschämt eine Web-Entwicklerin nach XAML zu fragen oder einen Hobby-Gamemodder, der gerade von der Schule kommt, nach Scrum. Trotzdem haben alle, die offen, aktiv und selbstmotiviert sind, das Potential großartige Developer zu sein.

Aber irgendwo muss ja anfangen. Deshalb hier meine kurze Liste von Themen, die mich brennend interessieren, wenn ich jemand von der programmierenden Menschheit kennen lernen will.

1. Technologie

Wie gut würden Sie Ihre Fähigkeiten als Programmierer/in einschätzen.
Auf der Skala von:
- Thema bekannt (gelesen, gehört, Vorlesung in der Uni)
- Etwas Praxis (probiert, Übungsaufgabe, mal verwendet)
- Viel Erfahrung (Profi-Level, kenne ich ziemlich gut)
- Ausgezeichnet (Wizard-Level, könnte das Ding selber schreiben)

Wizard-Level bedeutet, z.B. bei XML einen XML Parser selbst zu schreiben, nicht "nur" einen XML Parser zu benutzen. Wizard-Level heißt den PHP Interpreter selber schreiben können, einen HTTP-Server, JUnit nicht nur benutzen, sondern eine alternative Unit Test Library selbst schreiben

Java, C#
MySQL
HTTP
HTML/CSS
SOAP
XMPP
JSON
OAuth
TCP/IP
boost, STL
Eclipse
CVS, Subversion, Git
Win32, MFC, COM, XAML
3D-Engines, welche?
Selenium
PHP, Python, Ruby on Rails, Perl
MS SQL Server, Oracle
XML
JavaScript
REST
Ajax
COMET, BOSH
Objective-C , Scala, Groovy, Erlang
C, C++
gcc
Profiling
EC2, S3, SQS
wxWidgets, Qt, Gtk
Maven, Ant, Hudson/Jenkins
Spring, Hibernate
Javascript Libraries, jQuery, ExtJS, andere?
Netzwerk Programmierung, sockets, andere?
Concurrency, Mutex, pthread, andere Thread-APIs?
Assembler, welche?
DevStudio, welche Versionen?
Text Editoren, was verwenden Sie zum Programmieren/Scripting?
Web-Server, Application Server, Tomcat, Apache, andere?
Template Engines, welche?
Caches, Memcache, Redis, Terracotta, andere?
Browser Extensions, für welche Browser?
Unit Test Frameworks, JUnit, NUnit, andere?
Logging Frameworks, log4net, log4j, andere?

2. Methodik
Wie gut kennen und wenn ja, seit wann verwenden Sie:

Objektorientierte Entwicklung
Agile Entwicklung
TDD
BDD
SOLID
DRY
MVC
Refactoring
Unit Tests
Automatisiertes UI Testing
Automatisierte Integrationstests
Code Coverage Analyse
Coding Conventions
Frequent Releases, wie "frequent"?
Pair Programming
Software Design Patterns
Scrum als Developer, Scrum Master, PO
Refactoring- und Coding-Werkzeuge in Entwicklungsumgebungen

3. Allgemein

Haben Sie Computer zuhause?
Welche(s) Betriebssystem(e)?
Einen Rechner oder ein Netzwerk?
Haben Sie eine Website? welche URL?
Bloggen, Twittern Sie oder benutzen Sie andere Social Networks?
Können Sie Linux installieren und verwalten? Welche Distribution?
Auf welchen Plattformen programmieren Sie? Windows, Mac, Linux, iOS?
Haben Sie Cross-Plattform Erfahrung?
Programmieren Sie gerne?
Programmieren Sie viel? wie viel? gut? sehr gut?
Haben Sie an Open-Source Projekten mitgearbeitet? welche?
Gibt es öffentlich zugängliche Projekte? URL?
Können Sie Code oder andere Arbeitsproben zeigen?