Network Your Software

Trusted by Industry Leaders

Ice

A Comprehensive RPC Framework

Flexible

Make synchronous and asynchronous invocations using TCP, UDP, SSL/TLS, WebSockets, and Bluetooth. Bidirectional connections allow a server to reuse a connection established by a client to make callbacks.

Secure

Ice offers powerful and easy to use security features. The IceSSL plug-in uses your operating system's SSL/TLS stack to encrypt your data and authenticate your connections.

Fast

Ice uses a compact, efficient binary protocol to minimize CPU and bandwidth consumption.

Everywhere

Develop in C++, C#, Java, JavaScript, MATLAB, Objective-C, PHP, Python, and Ruby. Deploy on Linux, macOS, Windows, Android, and iOS.

An Introduction to

Ice

Slice - Ice's Interface Definition Language

// Printer.ice
module Demo
{
    interface Printer
    {
        // A client can invoke this operation on a server.
        // In this example we print the string s
        void printString(string s);
    }
}

Compile Slice to C++, C#, Java, ...

$ slice2cpp    Printer.ice      # Printer.h, Printer.cpp
$ slice2cs     Printer.ice      # Printer.cs
$ slice2java   Printer.ice      # Demo/Printer.java, ...
$ slice2js     Printer.ice      # Printer.js
$ slice2matlab Printer.ice      # +Demo/PrinterPrx.m
$ slice2objc   Printer.ice      # Printer.h, Printer.m
$ slice2php    Printer.ice      # Printer.php
$ slice2py     Printer.ice      # Printer.py
$ slice2rb     Printer.ice      # Printer.rb
$ slice2swift  Printer.ice      # Printer.swift
//
// Implement Printer interface
// class PrinterI : public Demo::Printer { public: virtual void printString(string s, const Ice::Current&) override { cout << s << endl; } };
// Initialize Ice communicator - used for interacting with the Ice runtime
Ice::CommunicatorHolder ich(argc, argv);

// Instantiate a new PrinterI servant - the implementation of your Printer
auto servant = make_shared<PrinterI>();

// Create object adapter - a container for your servants. Listens on port 10000
auto adapter = ich->createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000");

// Add the servant object to the object adapter with identity "SimplePrinter"
adapter->add(servant, ich->stringToIdentity("SimplePrinter"));

// Activate object adapter - accept incoming requests and dispatch them to servants
adapter->activate();

// Wait for communicator to shut down
ich->waitForShutdown();
//
// Implement Printer interface
// public class PrinterI : Demo.PrinterDisp_ { public override void printString(string s, Ice.Current current) { Console.WriteLine(s); } }
// Initialize Ice communicator - used for interacting with the Ice runtime
using(var communicator = Ice.Util.initialize(ref args))
{
    // Instantiate a new PrinterI servant - the implementation of your Printer
    var servant = new PrinterI();

    // Create object adapter - a container for your servants. Listens on port 10000
    var adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000");

    // Add the servant object to the object adapter with identity "SimplePrinter"
    adapter.add(servant, communicator.stringToIdentity("SimplePrinter"));

    // Activate object adapter - accept incoming requests and dispatch them to servants
    adapter.activate();

    // Wait for communicator to shut down
    communicator.waitForShutdown();
}
//
// Implement Printer interface
// public class PrinterI implements Demo.Printer { @Override public void printString(String s, com.zeroc.Ice.Current current) { System.out.println(s); } }
// Initialize Ice communicator - used for interacting with the Ice runtime
try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args))
{
    // Instantiate a new PrinterI servant - the implementation of your Printer
    com.zeroc.Ice.Object servant = new PrinterI();

    // Create object adapter - a container for your servants. Listens on port 10000
    com.zeroc.Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000");

    // Add the servant object to the object adapter with identity "SimplePrinter"
    adapter.add(servant, communicator.stringToIdentity("SimplePrinter"));

    // Activate object adapter - accept incoming requests and dispatch them to servants
    adapter.activate();

    // Wait for communicator to shut down
    communicator.waitForShutdown();
}
//
// Implement Printer interface
// @interface PrinterI : DemoPrinter<DemoPrinter> @end @implementation PrinterI -(void) printString:(NSMutableString*)s current:(ICECurrent*)current { printf("%s\n", [s UTF8String]); } @end
// Initialize Ice communicator - used for interacting with the Ice runtime
id<ICECommunicator> communicator = communicator = [ICEUtil createCommunicator:&argc argv:argv];

// Instantiate a new PrinterI servant - the implementation of your Printer
ICEObject *servant = [PrinterI printer];

// Create object adapter - a container for your servants. Listens on port 10000
id<ICEObjectAdapter> adapter = [communicator createObjectAdapterWithEndpoints: @"SimplePrinterAdapter"
                                                  endpoints: @"tcp -p 10000"];

// Add the servant object to the object adapter with identity "SimplePrinter"
[adapter add:servant identity:[communicator stringToIdentity:@"SimplePrinter"]];

// Activate object adapter - accept incoming requests and dispatch them to servants
[adapter activate];

// Wait for communicator to shut down
[communicator waitForShutdown];

// Destroy Ice communicator
[communicator destroy];
#
# Implement Printer interface
# class PrinterI(Demo.Printer): def printString(self, s): print(s)
# Initialize Ice communicator - used for interacting with the Ice runtime
with Ice.initialize(sys.argv) as communicator:
    # Instantiate a new PrinterI servant - the implementation of your Printer
    servant = PrinterI()

    # Create object adapter - a container for your servants. Listens on port 10000
    adapter = communicator.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "tcp -p 10000")

    # Add the servant object to the object adapter with identity "SimplePrinter"
    adapter.add(servant, communicator.stringToIdentity("SimplePrinter"))

    # Activate object adapter - accept incoming requests and dispatch them to servants
    adapter.activate()

    # Wait for communicator to shut down
    communicator.waitForShutdown()
//
// Implement Printer interface
// class PrinterI: Printer { func printString(s: String) { print(s) } }
// Initialize Ice communicator - used for interacting with the Ice runtime
let communicator = try Ice.initialize(CommandLine.arguments)
defer { communicator.destroy() }

// Instantiate a new PrinterI servant - the implementation of your Printer
let servant = PrinterI()

// Create object adapter - a container for your servants. Listens on port 10000
let adapter = try communicator.createObjectAdapterWithEndpoints(name: "SimplePrinterAdapter", endpoints: "tcp -p 10000")

// Add the servant object to the object adapter with identity "SimplePrinter"
try adapter.add(servant: PrinterDisp(servant), id: Ice.stringToIdentity("SimplePrinter"))

// Activate object adapter - accept incoming requests and dispatch them to servants
try adapter.activate()

// Wait for communicator to shut down
communicator.waitForShutdown()
// Initialize Ice communicator - used for interacting with the Ice runtime
Ice::CommunicatorHolder ich(argc, argv);

// Create a proxy to the remote Printer object
auto obj = ich->stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");

// Downcast obj to Printer proxy
auto printer = Ice::checkedCast<PrinterPrx>(obj);

// Invoke "printString" operation on remote Printer object
printer->printString("Hello World!");
// Initialize Ice communicator - used for interacting with the Ice runtime
using(var communicator = Ice.Util.initialize(ref args))
{
    // Create a proxy to the remote Printer object
    var obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");

    // Downcast obj to Printer proxy
    var printer = Demo.PrinterPrxHelper.checkedCast(obj);

    // Invoke "printString" operation on remote Printer object
    printer.printString("Hello World!");
}
// Initialize Ice communicator - used for interacting with the Ice runtime
try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args))
{
    // Create a proxy to the remote Printer object
    com.zeroc.Ice.ObjectPrx obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");

    // Downcast obj to Printer proxy
    Demo.PrinterPrx printer = Demo.PrinterPrx.checkedCast(obj);

    // Invoke "printString" operation on remote Printer object
    printer.printString("Hello World!");
}
// Initialize Ice communicator - used for interacting with the Ice runtime
id<ICECommunicator> communicator = [ICEUtil createCommunicator:&argc argv:argv];

// Create a proxy to the remote Printer object
id<ICEObjectPrx> obj = [communicator stringToProxy:@"SimplePrinter:tcp -h serverhost.serverdomain -p 10000"];

// Downcast obj to Printer proxy
id<DemoPrinterPrx> printer = [DemoPrinterPrx checkedCast:obj];

// Invoke "printString" operation on remote Printer object
[printer printString:@"Hello World!"];

// Destroy Ice communicator
[communicator destroy];
# Initialize Ice communicator - used for interacting with the Ice runtime
with Ice.initialize(sys.argv) as communicator:
    # Create a proxy to the remote Printer object
    obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000")

    # Downcast obj to Printer proxy
    printer = Demo.PrinterPrx.checkedCast(obj)

    # Invoke "printString" operation on remote Printer object
    printer.printString("Hello World!")
// Initialize Ice communicator - used for interacting with the Ice runtime
const communicator = Ice.initialize();

// Create a proxy to the remote Printer object
const obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");

// Downcast obj to Printer proxy
const printer = await Demo.PrinterPrx.checkedCast(obj);

// Invoke "printString" operation on remote Printer object
await printer.printString("Hello World!");

// Destroy Ice communicator
communicator.destroy();
% Initialize Ice communicator - used for interacting with the Ice runtime
communicator = Ice.initialize();

% Create a proxy to the remote Printer object
obj = communicator.stringToProxy('SimplePrinter:tcp -h serverhost.serverdomain -p 10000');

% Downcast obj to Printer proxy
printer = Demo.PrinterPrx.checkedCast(obj);

% Invoke "printString" operation on remote Printer object
printer.printString('Hello World!');

% Destroy Ice communicator
communicator.destroy();
// Initialize Ice communicator - used for interacting with the Ice runtime
$communicator = Ice\initialize();

// Create a proxy to the remote Printer object
$obj = $communicator->stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000");

// Downcast obj to Printer proxy
$printer = Demo\PrinterPrxHelper::checkedCast($obj);

// Invoke "printString" operation on remote Printer object
$printer->printString("Hello World!");

// Destroy Ice communicator
$communicator->destroy();
# Initialize Ice communicator - used for interacting with the Ice runtime
communicator = Ice::initialize(ARGV)

# Create a proxy to the remote Printer object
obj = communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000")

# Downcast obj to Printer proxy
printer = Demo::PrinterPrx::checkedCast(obj)

# Invoke "printString" operation on remote Printer object
printer.printString("Hello World!")

# Destroy Ice communicator
communicator.destroy();
// Initialize Ice communicator - used for interacting with the Ice runtime
let communicator = try Ice.initialize(CommandLine.arguments)
defer { communicator.destroy() }

// Create a proxy to the remote Printer object
let obj = try communicator.stringToProxy("SimplePrinter:tcp -h serverhost.serverdomain -p 10000")!

// Downcast obj to Printer proxy
let printer = try checkedCast(prx: obj, type: PrinterPrx.self)!

// Invoke "printString" operation on remote Printer object
try printer.printString("Hello World!")

Asynchronous Programming using Futures and Async/Await

Write concise and clean applications with standard language classes and constructs.

// Person.ice
module Demo
{
    interface Person
    {
        int computeCreditScore();
    }
}
// Obtain person proxy
auto person = ...

// Invoke "computeCreditScore" asynchronously on remote Person object
std::future<int> future = person->computeCreditScoreAsync();

//
// Do other work
// // Retrieve result from future auto creditScore = future.get();
// Obtain person proxy
var person = ...

// Invoke "computeCreditScore" asynchronously on remote Person object
// and await the result (must be called from an async function)
var creditScore = await person.computeCreditScoreAsync();
// Obtain person proxy
Demo.PersonPrx person = ...

// Invoke "computeCreditScore" asynchronously on remote Person object
CompletableFuture<Integer> future = person.computeCreditScoreAsync();

//
// Do other work
// // Retrieve result from future Integer creditScore = future.get();
# Obtain person proxy
person = ...

# Invoke "computeCreditScore" asynchronously on remote Person object
creditScore = await Ice.wrap_future(person.computeCreditScoreAsync())
// Obtain person proxy
const person = ...

// Invoke "computeCreditScore" asynchronously on remote Person object
// and await the result (must be called from an async function)
const creditScore = await person.computeCreditScore();
% Obtain person proxy
person = ...

% Invoke "computeCreditScore" asynchronously on remote Person object
future = person.computeCreditScoreAsync()

%
% Do other work
% % Retrieve result from future creditScore = future.fetchOutputs()
// Obtain person proxy
let person = ...

// Invoke "computeCreditScore" asynchronously on remote Person object
// Ice for Swift uses PromiseKit for its async API
firstly {
  person.computeCreditScoreAsync()
}.then { creditScore in
  // Use result
}

Language Mappings

Ice for C++Ice for C#Ice for JavaIce for JavaScriptIce for MATLABIce for Objective-CIce for PHPIce for PythonIce for RubyIce for Swift

Ice Services

Ice is more than a RPC framework. It also provides a number of complementary services for your networked applications.

IceGrid

Deployment and Monitoring

Glacier2

Firewall Traversal

IceStorm

Event Publish/Subscribe

Get Started with Ice

Whether you're working on an enterprise application or hobbyist project, Ice makes it easy to network your software.

Download Ice  Documentation