Previous Topic

Next Topic

Book Contents

Book Index

I/O Connector Service Developer Guide

Using the Service

Each bundle that needs a connection must get the I/O 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.

On finishing all your work or getting unregistered, close the opened connection.

The usage of the OSGi communication model is illustrated through two example classes (listings 1.1 and 1.2) packed in two separate bundles which communicate over the socket scheme.

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.

Listing 1. Using the IO Connector Service to create a server socket connection.

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",
                                                            ConnectorService.READ);
      } catch(ConnectionNotFoundException ce) {
        ce.printStackTrace();
      } catch(IOException ioe) {
        ioe.printStackTrace();
      }
    }
    start();
  }
  
  public void run() {
    try {
      //accepting the data input from clients
      connection = server.acceptAndOpen();
      DataInputStream inputStream = connection.openDataInputStream();
      while(true) {
        String input = inputStream.readUTF();//we expect String data
        while(input != null) {
          System.out.println(input);
          input = inputStream.readUTF();
        }
      }      
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  public void stop(BundleContext bc) {
    try {
      connection.close();//finally, we close the connection

    } catch(IOException ioe) {
      ioe.printStackTrace();
    }
    bc.ungetService(connRef);    
  }
}

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.

Listing 2. Using the IO Connector Service to create a client socket connection.

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.

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.