The Java API for Skype is develope by
Hisano using eclipse SWT library. It can be downloaded here (
http://sourceforge.jp/projects/skype/files/). Unfortunately, I'm not able to find sufficient documentation for it. Here is some note made by Terry who tried this API
01. The Skype API on Windows.
These notes assume the reader has:
a. solid experience with the most current JDK;
b. at least browsed the documentation on the Skype 2.0 API; and
c. has looked at the examples from the Skype API Guide.
The notes DO NOT assume that the reader has:
a. actually tried to build an application using any of those other
wrappers or interfaces to the Skype API;
b. an in-depth understanding of the Windows Win32 API; nor
c. an in-depth understanding of SWT.
The key characteristics of the Skype API are:
a. it uses a Windows interprocess communication protocol based on Messages;
b. the protocol is basically asynchronous and stateless.
There is no particular send-receive sequence that your Java Client application can use in 'blocking mode' to obtain a known copy of the Skype Client's state. The Skype client must effectively be treated as a 'black box' that sends messages to your client either in response
to specific requests for information or as unsolicited notification events.
02. The Java Skype Interface Architecture.
A Connector class object is used to encapsulate the communication between the Skype Client and your Java Client. The Windows version of that abstract class is W32Connector. That is where the SWT wrapper for Microsoft's Win32 API is used to establish and maintain a path by
which message requests can be sent to the Skype Client and messages received from the Skype Client can be passed back to your application as simple Strings. This 'Loop Forever' listening code runs as a separate Thread, "Win32EventDispatcher".
NOTE # 1 for SWT Programmers: The loop used is the standard SWT event processing loop. If you are using this library in a true SWT application, you already have a well-known place where you invoke this loop logic. If this library's use of that loop causes your application to fail, it might be better to replace it with Thread.wait logic that could be notified when your application is ready to shutdown. If your application does not use any SWT U/I, it is a daemon-like service,
this method of loop-waiting should work just fine.
NOTE # 2 for SWT Programmers: Messages sent from your Java Client application to the Skype Client are scheduled through the SWT event-handling thread. I don't think this approach is really necessary as the sendCommand code does not 'touch' any Display-managed code. If your use of this library involves a lot message sending, you may want to reduce some of the overhead
by removing the dependence upon 'Display.asychExec'; otherwise, there is probably no harm in this 'protective' programming approach.
03. Java Skype Callbacks.
The 'hooks' for your Java Client application to respond to what is going on with the Skype Client are constructed as Listeners. Depending upon what Skype Client activity you want to handle,
you will add one of these Listeners:
a. Connector.
b. Call.
c. CallReceived.
d. MessageReceived.
e. Application.
f. Stream.
The Connector Listener Interface is the most import one. Its messageReceived method is called back for every message sent by the Skype Client. However, because it is so important, the Java Skype library performs some automatic processing on the messages in addition to whatever processing your application might require.
One such 'automatic processing' is debugging. If you turn on debugging, incoming message traffic is written to stdout. I recommend you change that to write to stderr. Output to stdout is buffered, so what you write does not always immediately make it to your screen. When trying to understand low-level message flows, if input and output debugging text is sometimes buffered, it is almost impossible to understand the real sequence of events represented by the flow of control in the code.
Alternately, and probably better for gaining understanding, do not turn on debugging mode, instead catch all the incoming messages and examine them in your own code. It turns out,
at least with the present code, that you have to examine all incoming message traffic in order to know when a call has ended.
The Call Listener Interface provides a statusChanged callback method. At the present time, that call back never seems to be made. It is apparently intended as a convenience for keeping
track of Call Status without having to intercept and process messageReceived on the Connector Listener Interface.
The Call Received Listener Interface is clearly just such a convenience; the callReceived method is invoked when the Connector Listener Interface detects the RINGING state change.
The Message Received Listener Interface is a similar convenience whose messageReceived callback will only be invoked when a new Instant Message is received from the Skype Client.
The Application Listener Interface may be a little confusing if you think that you are writing an application. You are writing an application, but the 'attaching' and 'unattaching' of your Java Client to the Skype Client IS NOT handled here. The attach-unattach state changes are handled through the Connector Listener Interface. This interface's connected and disconnected methods are only called back when you try to use the APP2APP part of the Skype API.
The Stream Listener Interface's textReceived and datagramReceived methods are only called back when message traffic through the APP2APP protocol is received by your Java Client.
04. Java Skype Thread Issues.
As mentioned above, because the Java Skype library borrows its COM interface from SWT, there are already a couple of threads involved as soon as your Java Client application gets
a Connector instance. That multi-threading, however, is just a by-product of the way a typical SWT application needs to be built in order to have fast screen rendering along with fast event processing; it is not really germane to our concerns.
When the "Win32EventDispatcher" does receive some incoming traffic from the Skype Client, it does fork a new Thread, "Win32MessageSender", for each message.
Note that it DOES NOT fork a new Thread for each Listener queued up to handle messageReceived; all such callbacks are handled 'first-in-first-out' in a single Thread. So, if your application's processing of any incoming traffic incurs delays, you need to fork a separate Thread to handle that work with the least interference for other Listeners behind you in the queue.
Beware that Connector's listener List can grow in ways that that you probably would not expect. Every message sent to the Skype Client [Connector.execute] pushes a new Listener on to the List. So, for example, if your Call Received Listener does something as simple as ask for the Call Type, a message will have to be sent to the Skype Client to obtain that information. That will push another Listener on to the List. The Call object really only has one field, ID, that it can
provide without a round-trip through the message-processing protocol.
There are obviously some changes to the Skype API that would be beneficial, but without those enhancements, there is little that the Java Skype library can do. We could imagine some 'intelligence' in the message-receiving layer that would, for example, upon receipt of a new Call, cache that information, make additional requests of the Skype Client, and only 'release' a new call to our application after the Call object had been populated with the additional fields. That would definitely make our work easier, but it would also delay Call notification and increase the error handling logic.
So, for now, the important guideline is: Fork a separate Thread for non-trivial message handling code, and even then, be careful about generating additional message traffic in your message handling code.