File : src/aws-server-push.ads
------------------------------------------------------------------------------
-- Ada Web Server --
-- --
-- Copyright (C) 2000-2003 --
-- ACT-Europe --
-- --
-- Authors: Dmitriy Anisimkov - Pascal Obry --
-- --
-- This library is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by --
-- the Free Software Foundation; either version 2 of the License, or (at --
-- your option) any later version. --
-- --
-- This library is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this library; if not, write to the Free Software Foundation, --
-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
-- this unit does not by itself cause the resulting executable to be --
-- covered by the GNU General Public License. This exception does not --
-- however invalidate any other reasons why the executable file might be --
-- covered by the GNU Public License. --
------------------------------------------------------------------------------
-- $Id: aws-server-push.ads,v 1.15 2003/10/29 09:32:48 obry Exp $
-- Package to support Server Push feature. This is only supported by Netscape
-- browsers. It will not work with Microsoft Internet Explorer.
-- For Microsoft Internet Explorer complementary active components
-- should be used like java applets or ActiveX controls.
with AWS.Net.Stream_IO;
with Table_Of_Strings_And_Static_Values_G;
generic
type Client_Output_Type (<>) is private;
-- Data type client want to send through server push.
type Stream_Output_Type (<>) is private;
-- Data type to be sent through the socket stream.
type Client_Environment is private;
-- Data type to keep client context. This context will be passed to the
-- conversion routine below.
with function To_Stream_Output
(Output : in Client_Output_Type;
Client : in Client_Environment)
return Stream_Output_Type;
-- Function used for convert Client_Output_Type to Stream_Output_Type.
-- This is used by the server to prepare the data to be sent to the
-- clients.
package AWS.Server.Push is
Client_Gone : exception;
-- Raised when a client is not responding.
Closed : exception;
-- Raised when trying to register to a closed push server.
Duplicate_Client_ID : exception;
-- Raised in trying to register an already registered client.
type Object is limited private;
-- This is the push server object. A push server has two modes, either it
-- is Open or Closed. When open it will send data to registered
-- clients. No data will be sent to registered client if the server is
-- Closed.
type Mode is (Plain, Multipart, Chunked);
-- Describeed the mode to communicate with the client.
-- Plain : no transformation is done, the data are sent as-is
-- Multipart : data are MIME encoded.
-- Chuncked : data are chunked, a piece of data is sent in small pieces.
subtype Client_Key is String;
-- The Client ID key representation. In a server each client must have a
-- uniq ID. This ID is used for registration and for sending data to
-- specific client.
procedure Register
(Server : in out Object;
Client_ID : in Client_Key;
Socket : in Net.Socket_Type'Class;
Environment : in Client_Environment;
Init_Data : in Client_Output_Type;
Init_Content_Type : in String := "";
Kind : in Mode := Plain;
Close_Duplicate : in Boolean := False);
-- Add client identified by Client_ID to the server subscription
-- list and send the Init_Data (as a Data_Content_Type mime content) to
-- him. After registering this client will be able to receive pushed data
-- from the server in brodcasting mode. If Close_Duplicate is True and
-- Client_ID is already registered into the list then old one will be
-- unregistered first (no exception will be raised).
procedure Register
(Server : in out Object;
Client_ID : in Client_Key;
Socket : in Net.Socket_Type'Class;
Environment : in Client_Environment;
Kind : in Mode := Plain;
Close_Duplicate : in Boolean := False);
-- Same as above but without sending initial data.
procedure Unregister
(Server : in out Object;
Client_ID : in Client_Key;
Close_Socket : in Boolean := True);
-- Removes client Client_ID from server subscription list. The associated
-- client's socket will be closed if Close_Socket is True. No exception is
-- raised if Client_ID was not registered.
procedure Unregister_Clients
(Server : in out Object;
Close_Sockets : in Boolean := True);
-- Remove all registered clients from the server. Closes if Close_Sockets
-- is set to True (default) otherwise the sockets remain open. After this
-- call the sever will still in running mode. Does nothing if there is no
-- client registered.
procedure Send_To
(Server : in out Object;
Client_ID : in Client_Key;
Data : in Client_Output_Type;
Content_Type : in String := "");
-- Push data to a specified client identified by Client_ID.
procedure Send
(Server : in out Object;
Data : in Client_Output_Type;
Content_Type : in String := "");
-- Push data to every client (broadcast) subscribed to the server.
generic
with procedure Client_Gone (Client_ID : in String);
procedure Send_G
(Server : in out Object;
Data : in Client_Output_Type;
Content_Type : in String := "");
-- Push data to every client (broadcast) subscribed to the server.
-- Call Client_Gone for each client with broken socket.
function Count (Server : in Object) return Natural;
-- Returns the number of registered clients in the server.
function Is_Open (Server : in Object) return Boolean;
-- Return True if the server is open, meaning server is still running,
-- ready to accept client's registration and still sending data to
-- clients.
-- Shutdown routines put the server in a Closed mode. The routines below
-- provides a way to eventually close the socket, to send some
-- finalisation data.
procedure Shutdown
(Server : in out Object;
Close_Sockets : in Boolean := True);
-- Unregisted all clients and close all associated connections (socket) if
-- Close_Socket is True. The server will be in Closed mode. After this
-- call any client trying to register will get the Closed exception. It is
-- possible to reactivate the server with Restart.
procedure Shutdown
(Server : in out Object;
Final_Data : in Client_Output_Type;
Final_Content_Type : in String := "");
-- Idem as above but it send Final_Data (as a Data_Content_Type mime
-- content) before closing connections.
procedure Shutdown_If_Empty
(Server : in out Object;
Open : out Boolean);
-- Server will be shutdown (close mode) if there is no more active clients
-- (Count = 0). Returns new server status in Open (Open will be True if
-- server is in Open mode and False otherwise). After this call any client
-- trying to register will get the Closed exception. It is possible to
-- reactivate the server with Restart.
procedure Restart (Server : in out Object);
-- Set server to Open mode. Server will again send data to registered
-- clients. It does nothing if server was already open.
private
subtype Stream_Access is AWS.Net.Stream_IO.Socket_Stream_Access;
type Client_Holder is record
Stream : Stream_Access;
Kind : Mode;
Environment : Client_Environment;
end record;
package Table is new Table_Of_Strings_And_Static_Values_G
(Character_Type => Character,
String_Type => String,
Less => "<",
Equals => "=",
Value_Type => Client_Holder);
protected type Object is
function Count return Natural;
-- Returns the number of registered client.
procedure Unregister_Clients (Close_Sockets : in Boolean);
-- Unregister al clients, close associated socket if Close_Socket is
-- set to True.
procedure Shutdown_If_Empty (Open : out Boolean);
-- See above.
procedure Restart;
-- See above.
procedure Shutdown
(Close_Sockets : in Boolean);
-- See above.
procedure Shutdown
(Final_Data : in Client_Output_Type;
Final_Content_Type : in String);
-- See above.
procedure Register
(Client_ID : in Client_Key;
Holder : in out Client_Holder;
Close_Duplicate : in Boolean);
-- See above.
-- Holder would be released in case of registration failure.
procedure Register
(Client_ID : in Client_Key;
Holder : in out Client_Holder;
Init_Data : in Client_Output_Type;
Init_Content_Type : in String;
Close_Duplicate : in Boolean);
-- See above.
-- Holder would be released in case of registration failure.
procedure Send_To
(Client_ID : in Client_Key;
Data : in Client_Output_Type;
Content_Type : in String);
-- See above.
procedure Send
(Data : in Client_Output_Type;
Content_Type : in String;
Unregistered : in out Table.Table_Type);
-- Send Data to all clients registered. Unregistered will contain a
-- list of clients that have not responded to the request. These
-- clients have been removed from the list of registered client.
procedure Unregister
(Client_ID : in Client_Key;
Close_Socket : in Boolean);
-- See above.
function Is_Open return Boolean;
-- See above.
private
Container : Table.Table_Type;
Open : Boolean := True;
end Object;
end AWS.Server.Push;