The Connector Service Bundle provides ProSyst's implementation of the OSGi IO Connector Service, specified in the OSGi Service Platform Specification Release 4. It supplies a model through which bundles can communicate with external resources through different connection implementations. The OSGi communication API applies the advantages of the J2ME architecture to the OSGi Service Framework. It allows creating applications that occupy small amounts of resources. It is easy to use and provides many different connection implementations simultaneously.
Note: Using the Connector Service Bundle make sense only when the Standard Version of mBeddedServer framework is used (see "Framework Versions" chapter of the current documentation). In case running the Connector Version of the framework the functionality of the Connector Service Bundle is implemented by the System Bundle.
Contents:
The JAR file of this bundle is connector.jar, located in the bundles folder.
|
|
The communication API of OSGi is defined for all bundles that require connectivity
to external computers or devices. It uses the J2ME Connection Framework, represented
by the javax.microedition.io API. This model is based on a Connector
class which manages many different connection implementors.
The OSGi Communication API replaces the javax.microedition.io.Connector
class from J2ME with its own ConnectorService interface (org.osgi.service.io.ConnectorService)
available as a service in the framework. This is necessary for the needs of
the OSGi Service Framework model. The OSGi IO Connector Service manages the
available connection implementations and creates connections requested by bundles.
Services which need to create connections must use the IO Connector Service.
They need NOT work directly with the connection implementors.
The communication implementations are registered as services called "connection
factories". They are represented by the org.osgi.service.io.ConnectionFactory
interface. Each connection factory declares the types of connections it implements
by registering for a particular scheme. A scheme is the protocol or pattern
of communication implemented. A bundle which demands a connection must pass
to the IO Connector Service a valid Uniform Resource Identifier (URI) starting
with the expected scheme. The scheme is the part of the URI before the first
":". When the IO Connector Service receives the URI, it parses it
and then redirects the URI to the appropriate connection factory.
Each bundle that needs to communicate must invoke some of the open
methods of the IO Connector Service. The connection factory found by the Connector
Service will create a javax.microedition.io.Connection object.
Figure 1: The connection-requester bundle uses the IO Connector Service to make the appropriate connection factory create the desired connection
This service is implemented as described in the OSGi specification. In addition, it possesses capabilities to dynamically detect new connection factory services registered with the framework.
When this service is registered, it checks for connection factories registered before its activation and starts listening for the registration of new connection factories.
If a connection factory is found (or a notification for its registration is
received), the IO Connector Service inspects its scheme. If there isn't a connection
factory already registered for that scheme, the new connection factory is added
to the list of known factories. If there is a connection factory already responsible
for that scheme, then the newly found one replaces the old one only if it has
higher ranking (a service's ranking is determined by the value of the org.osgi.framework.Constants.SERVICE_RANKING
( "service.ranking") property with which it is registered
by the registerService method).
When the open method of the IO Connector Service is invoked by some
bundle needing a connection, there are two possibilities:
javax.microedition.io.Connection
is created.javax.microedition.io.Connection
but also org.mbs.services.io.ConnectionNotifier. In this way
the bundle initiator of the connection can register ConnectionListener-s,
which will notify it when the connection is actually created or closed. So,
when a new connection factory responsible for the requested scheme is registered
with the framework, the connection will become "real" and will be
removed from the list of "fictive" connections.This pattern is visualized in Figure 1.

Figure 2: How the IO Connector Service creates connections
The IO Connector Service creates each connection by invoking the connection
factory's createConnection method. Before the connection is initiated,
the Connector Service parses the requested URI and then places its components
into a Dictionary, so that the ConnectionFactory will
be able to get only the components it needs.
A connection has three modes: read, write and read&write. They are defined
as constants in the ConnectorService interface and can be passed
as a parameter to the open method. If no mode is passed, the read&write
mode is implied.
Tip: You can obtain a normal java.io stream
instead of a javax.microedition.io.Connection by using the openOutputStream
/ openDataOutputStream methods.
Note: If the connection factory or the Connector Service
gets unregistered, the connection factory's close() method is invoked
to withdraw all connections currently available in the connection factory.
The generic connection interface obtained through the IO Connector Service is
javax.microedition.io.Connection. However, this interface is not
convenient to use because it contains only one method: the close()
method. The open method is not defined here because the opening
of a connection is always handled by the IO Connector Service.
The javax.microedition.io package contains a set of much more
convenient connections extending the generic interface. Figure 3 shows the connection
hierarchy in the package.
Figure 3: Connection hierarchy in javax.microedition.io
Most connection factories created by ProSyst return not the generic connection itself but some of its inheritants. They contain useful methods allowing you to send and/or receive data through input/output streams or datagram packets. See each connection factory's description in the Connection Category chapter for details about the connection types supported by it.
The format of the URI must be composed according to RFC 2396 (Uniform Resource Identifiers (URI): Generic Syntax). Usually, the form of a URI is: <scheme>:<target>[<params>], where parts enclosed in [..] are optional. For example:
socket://127.0.0.1:1449
sms://+46705950899
As already mentioned, each bundle that needs a connection must get the IO Connector Service and invoke some variant of its open method. The bundle
requester does not need to work directly with connection factories. The IO Connector Service
handles processing all registered connection factories and decides which particular connection factory
to use.
Note: On finishing all your work or getting unregistered, close the opened connection.
We'll illustrate using the OSGi communication model through two example classes (listings 1.1 and 1.2) packed in two separate bundles which communicate over the socket scheme. This scheme is implemented by the Socket Connection Bundle. See its description for more details. The socket pattern requires there to be a server connection (i.e. a server-side TCP/IP socket to be listening) and a client connection opened. Hence, the first bundle will create a server connection waiting for client connections, and the second bundle will create a client connection passing some data to the server. The client and the server URIs are formed according to the syntax required by the Socket Connection Bundle.
import org.osgi.service.io.ConnectorService;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.io.StreamConnectionNotifier;
import java.io.DataInputStream;
import org.osgi.framework.*;
import java.io.IOException;
public class IOServer extends Thread implements BundleActivator {
private ServiceReference connRef;
private ConnectorService connService;
private StreamConnection connection;
private StreamConnectionNotifier server;
public void start(BundleContext bc) {
connRef = bc.getServiceReference(ConnectorService.class.getName());
if (connRef != null) {
connService = (ConnectorService)bc.getService(connRef);
try {
//Creates a read-only server connection on port 3333
server = (StreamConnectionNotifier)connService.open("socket://:3333",
|
Note that the connection created by the above example is an instance of StreamConnectionNotifier.
This is allowed by the implementation of the Socket Connection Bundle.
import org.osgi.service.io.ConnectorService;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.ConnectionNotFoundException;
import java.io.DataOutputStream;
import org.osgi.framework.*;
import java.io.IOException;
public class IOClient implements BundleActivator {
private ServiceReference connRef;
private ConnectorService connService;
private StreamConnection connection;
public void start(BundleContext bc) {
connRef = bc.getServiceReference(ConnectorService.class.getName());
if (connRef != null) {
connService = (ConnectorService)bc.getService(connRef);
try {
//passing the client socket URI. Note that we create a StreamConnection
connection = (StreamConnection)connService.open("socket://localhost:3333");
DataOutputStream outputStream = connection.openDataOutputStream();
//the simple String data sent to the server
outputStream.writeUTF("Hello there from the client!");
} catch(ConnectionNotFoundException ce) {
ce.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
public void stop(BundleContext bc) {
try {
connection.close();//not forgetting to close the connection
} catch(IOException ioe) {
ioe.printStackTrace();
}
bc.ungetService(connRef);
}
}
|
The client bundle sends a greeting String to the server, which prints it in
the system output. The created client connection is an instance of StreamConnection.
Note: If you start the two example bundles on different frameworks, you will need an IO Connector Service and a socket connection factory running on each of the frameworks. In this case, change the URIs passed to the Connector.
The Connector Service Bundle owns the following user-configurable system properties:
|
If you set/change these properties after the bundle has been activated, you must restart it so that it will accept the new values.