Tivoli Service Desk 6.0 Developer's Toolkit - Guia de Programação do Script

Capítulo 11: Conceitos sobre Rede

Retornar ao Índice


Introdução

Este capítulo foi desenvolvido para introduzir os conceitos fundamentais necessários para utilizar as instruções de extensão da rede TSD Script, a fim de que se comuniquem através de sua rede. Este capítulo descreve também conceitos especiais sobre rede e constantes e instruções de rede TSD Script.
Estas instruções do TSD Script podem ser utilizadas para personalizar o código fonte de seus aplicativos instalados ou criar seu próprio aplicativo distribuído TSD Script personalizado.

O que você precisa saber

Embora este capítulo aborde alguns aspectos fundamentais dos princípios de rede e linguagem do TSD Script, presume-se que você esteja familiarizado com ambas as áreas. Se você for modificar um aplicativo, convém trabalhar com alguém que tenha personalizado outros aplicativos ou que tenha utilizado TSD Script e Developer's Toolkit.

Arquiteturas de rede

As instruções incluídas como a linguagem do TSD Script permitem dois tipos distintos de arquiteturas de rede:

Neste capítulo, a descrição dos serviços de rede do TSD Script é geralmente aplicável a ambas arquiteturas. Onde as diferenças existirem entre as arquiteturas, elas serão especificadas.

Terminologia de Rede

Há vários termos utilizados para descrever as interações entre computadores em uma rede. Embora você possa estar familiarizado com alguns ou todos os termos, eles serão definidos aqui especificamente no contexto em que são utilizados com as extensões de rede do TSD Script.

Comunicação bidirecional

A comunicação Bidirecional ocorre quando duas máquinas desempenham ambas funções de cliente e servidor. Em outras palavras, a Máquina A (cliente) pode solicitar que a Máquina B (servidor) execute algum serviço. Da mesma forma, a Máquina B pode trocar funções e se tornar cliente solicitando que a Máquina A execute algum serviço. Consulte também a definição de conexão de reverso. Consulte ponto a ponto.

Cliente

Client é um aplicativo que solicita um serviço de um servidor. Um exemplo para cliente é uma estação de trabalho em uma conexão de rede para um servidor de arquivos. A conexão é iniciada pelo cliente.

Conexão

Conexão é a ligação lógica entre um cliente e um servidor.

Rotina de Tratamento de Eventos

Rotina de tratamento de eventos é uma função especial do TSD Script projetada para processar eventos assíncronos. As rotinas de tratamento de eventos são executadas no servidor a fim de processar pedidos de rede de um serviço.

Identificador

Cada conexão possui um identificador. O identificador contém as informações sobre a máquina cliente e o serviço que o servidor está fornecendo.

Servidor TSD Script

Servidor TSD Script é um processo do TSD Script que está sendo executado em um computador em rede que fornece um serviço.

Rotina de tratamento de eventos local

Rotina de tratamento de eventos local é a rotina de tratamento de eventos operando na máquina local. Se esta rotina de tratamento de eventos estiver efetuando pedidos de uma máquina diferente, a máquina será um servidor.

Instruções NETx

As Instruções NETx, ou extensões, são as instruções do TSD Script que começam com o prefixo NET. Estas instruções foram criadas para permitir que os aplicativos TSD Script se comuniquem através de uma rede.

Ambiente ponto a ponto

Ambiente ponto a ponto é aquele em que uma única máquina pode desempenhar a função tanto de cliente quanto de servidor.

Registro

O Registro de uma rotina de tratamento de eventos associará a rotina de tratamento a uma fonte de eventos.

Conexão de reverso

Uma conexão de reverso pode ser estabelecida em um ambiente ponto a ponto quando um servidor solicita a um cliente que execute serviço eficientemente, trocando as funções de cliente e servidor. Para lidar com estas comunicações, é estabelecida uma conexão de reverso entre o servidor local e o remoto.

Servidor

Servidor é uma máquina que fornece um serviço a um cliente. Um exemplo de servidor é uma impressora da rede.

Serviço

Serviço é a função executada pelo servidor. Se uma impressora for um servidor, o serviço que fornecerá será a impressão.

Rotinas de Tratamento de Eventos

As rotinas de tratamento de eventos são utilizadas em todo do TSD Script e Developer's Toolkit para suportar um ambiente orientado por eventos. Em um ambiente orientado por eventos, um evento (como uma digitação, um clique no mouse ou uma mensagem da rede) dispara, pelo aplicativo, a resposta apropriada (abertura de uma nova caixa de diálogo ou a seleção de uma entrada em um campo). Para processar eventos, cada aplicativo utiliza rotinas de tratamento de eventos projetadas especificamente para eles.

Os aplicativos que utilizam as rotinas de tratamento de eventos não precisam perguntar ou "controlar" eventos da rede. Normalmente, as rotinas de tratamento de eventos "dormem" (não estão ativas) até que ocorra um evento, então, processam um pedido para o serviço.

Um único servidor pode ter múltiplas rotinas de tratamento de eventos. Cada rotina de tratamento de eventos é projetada para fornecer um serviço específico ou um conjunto de serviços relacionados, conforme será explicado posteriormente neste capítulo.

Como definir rotinas de tratamento de eventos

As rotinas de tratamento de eventos são definidas na seção de rotinas de um programa TSD Script. As rotinas de tratamento de eventos da rede devem ser declaradas como tipo NETCONNECTION.

Este tipo de rotina de tratamento de eventos é diferente do tipo padrão, WINDOW. Uma vez que o tipo determina o $Handle que será utilizado, apenas as rotinas de tratamento de eventos do tipo NETCONNECTION poderão ser utilizadas com as instruções NETx.

NETCONNECTION EVENT TalkConnectEvent(REF whdl: WINDOW )IS

Rotinas de Tratamento de Eventos NetRegister e NetListen

Ao definir uma rotina de tratamento de eventos, é necessário também registrar seu serviço, conforme descrito nas seções a seguir. O Registro de uma rotina de tratamento de eventos associará a rotina de tratamento a uma fonte de eventos.

Há duas instruções diferentes que você pode utilizar para registrar uma rotina de tratamento de eventos:

As rotinas de tratamento de eventos registradas com NetRegister são chamadas rotinas de tratamento de eventos NetRegister. As rotinas de tratamento de eventos registradas com NetListen são chamadas rotinas de tratamento de eventos NetListen.

Este capítulo enfoca o uso do NetRegister, o qual é utilizado freqüentemente em rotinas de tratamento de eventos "padrão". Para a personalização de rotinas de tratamento de eventos, consulte a seção "Instruções Avançadas" neste capítulo.

Como registrar uma rotina de tratamento de eventos e seu serviço

Você deve registrar uma rotina de tratamento de eventos com o servidor para que ela receba e processe pedidos de serviço. Para registrar uma rotina de tratamento de eventos com a instrução NetRegister, utilize a seguinte sintaxe:

 NetRegister( TalkConnectEvent, 'Talk' ); 

Ao registrar uma rotina de tratamento de eventos, você especifica o nome do serviço que é fornecido. Serviço é uma categoria de ações executadas pela rotina de tratamento de eventos.

No exemplo a seguir, o nome do serviço definido para a rotina de tratamento de eventos da rede TalkConnectEvent é Talk.

NETCONNECTION EVENT TalkConnectEvent(REF whdl: WINDOW )IS
ACTIONS
.
..
END;
 NetRegister( TalkConnectEvent, 'Talk' );

Como utilizar portas com uma conexão de rede

Além dos serviços observados anteriormente, a extensão do número de uma porta especifica uma porta IP. O número da porta controla:

A porta padrão é 5001, e o serviço padrão é asenet/tcp. Se o serviço estiver no arquivo de serviços, será utilizado asenet/tcp no lugar do número padrão.

O número de uma porta pode ser especificado no prompt de comandos com o seguinte comando:

/p=nnn 

O número de uma porta emitido a partir de um prompt de comandos substituirá a porta padrão e o serviço padrão.

Nota: Os números da porta devem ser o mesmo para o cliente e o servidor.

Como criar um serviço curinga

É possível criar uma rotina de tratamento de eventos com um serviço definido como uma seqüência de comprimento zero ('') ou $Unknown. Este tipo de serviço é chamado serviço curinga.

Quando um serviço curinga é definido no servidor, ele atende a qualquer pedido especificado pelo cliente ao qual o servidor não pode encontrar um nome de serviço correspondente.

Você também pode definir um serviço curinga no cliente. Nesse caso, o servidor deve ter um serviço com o nome do serviço de '' ou $Unknown.

Nota: Um serviço curinga pode ser definido somente ao registrar a rotina de tratamento de eventos com a instrução NetRegister. (NetListen sempre utiliza um serviço curinga.)

Gabaritos

Ao registrar uma rotina de tratamento de eventos, no servidor é definido um gabarito para o serviço. Este gabarito inclui informações da definição da rotina de tratamento de eventos na seção de rotinas do código, bem como informações especificadas quando a rotina de tratamento de eventos foi registrada.

O gabarito é mantido no armazenamento até que uma conexão seja solicitada. Então, as informações no gabarito são utilizadas para criar a ocorrência do serviço para a conexão.

Como alterar uma rotina de tratamento de eventos e seus gabaritos


Há dois tipos básicos de alterações que podem ser feitas em um gabarito:

A qualquer hora que precisar fazer alterações em um gabarito, você poderá registrar novamente a rotina de tratamento de eventos ou registrar seu serviço. Ao registrar novamente uma rotina de tratamento de eventos, os novos valores de parâmetros serão imediatamente implementados. Todas as novas conexões abertas para o gabarito utilizarão novos valores. As conexões já existentes não serão afetadas pela(s) alteração(ções) no gabarito.

Atenção: Você deve especificar o nome do serviço exatamente como foi especificado no gabarito original. Caso contrário, a instrução NetRegister criará um novo gabarito para a rotina de tratamento de eventos e o gabarito existente não será modificado.

Como fazer que uma rotina de tratamento de eventos pare de processar pedidos

Após um gabarito ser criado, ele se torna imediata e continuadamente receptivo aos pedidos de serviço. Entretanto, o gabarito pode, a qualquer momento, ser interrompido de responder aos pedidos de serviço. Para isso, você deve registrar novamente o serviço com a rotina de tratamento de eventos especial $NullHandler:

NetRegister ($Nullhandler, 'service'); 

Nesta sintaxe, "service" é o nome do serviço associado a rotina de tratamento de eventos que deseja parar.

Após registrar novamente o serviço com $NullHandler, os pedidos futuros de serviço a partir do gabarito serão negados, mas quaisquer conexões existentes que utilizam o gabarito não serão afetadas.

Se precisar reiniciar o servidor, será necessário registrar novamente a rotina de tratamento de eventos e o serviço.

Como obter host (servidor) e informações sobre serviço

Uma rotina de tratamento de eventos pode servir conexões com muitos clientes diferentes. Pelo simples fato de ver o identificador da conexão, pode ser difícil determinar o serviço que está sendo executado.

Da mesma maneira, pode ser difícil determinar qual servidor está executando o serviço ou qual cliente está sendo servido. Isso aplica-se à rotina de tratamento de eventos NetListen, que responde a cada pedido de serviço que retém e que compartilha seus dados de ocorrência.

O TSD Script fornece duas instruções que podem ser utilizadas para obter informações sobre o host (servidor) e sobre o serviço a partir de um identificador de conexão:

Devido ao TSD Script suportar uma arquitetura cliente/servidor, bem como uma arquitetura ponto a ponto, a instrução NetGetHostName é projetada para obter informações sobre a máquina remota, independentemente se ela está desempenhando a função de servidor ou não.

Se você chamar a instrução NetGetHostName no cliente, obterá informações sobre o servidor. Se chamar a instrução NetGetHostName no servidor, obterá o nome do cliente.

Como estabelecer comunicação local entre rotinas de tratamento de eventos

Provavelmente há muitas rotinas de tratamento de eventos NETCONNECTION em qualquer servidor. Convém que, ocasionalmente, você passe mensagens entre elas. Devido ao fato de não ser eficiente enviar estas mensagens através da rede, o Developer's Toolkit fornece a instrução NetLoopBack. NetLoopBack permite enviar uma mensagem a uma rotina de tratamento de eventos da rede a partir de sua máquina local.

Conexões

Os aplicativos de rede do TSD Script utilizam um protocolo baseado em conexão. A interação entre máquinas em uma rede ocorre através de uma conexão. Para que um servidor forneça um serviço solicitado a um cliente, uma conexão deve estar aberta.
Há três elementos em cada conexão:

É a combinação destes três elementos que tornam uma conexão exclusiva. O processo de abertura e fechamento de uma conexão chama cada um destes elementos.

Várias conexões podem ser abertas entre um cliente e um servidor. Entretanto, um cliente pode ter apenas uma conexão aberta para um serviço específico em um servidor/porta.

Nota: Se uma conexão já estiver aberta entre um cliente e uma rotina de tratamento de eventos específica em um servidor, a solicitação de um serviço específico retornará o identificador da conexão existente.

Após registrar uma rotina de tratamento de eventos e seu serviço associado, o servidor estará pronto para reter pedidos do serviço especificado.


Como abrir uma conexão

Esta seção descreve o processo de abertura de uma conexão e lista as etapas para o procedimento utilizado para abrir uma conexão.

A seguir, os procedimentos para abrir uma conexão e uma explicação de cada etapa.

  1. O cliente envia um pedido de conexão ao servidor chamando a instrução NetConnect.
  2. Quando um cliente solicita um serviço, ele deve especificar o nome exato do serviço que precisa. (O nome do serviço é definido quando a rotina de tratamento de eventos é registrada no servidor.) Não há uma lista abrangente de serviços disponíveis fornecidos por um servidor e nos nomes de serviço não há distinção entre maiúsculas e minúsculas.

    Uma porta pode ser especificada como parte da cadeia de serviços. Se nenhuma porta for especificada, será utilizada a padrão.

    Um cliente pode solicitar um serviço curinga especificando uma seqüência de comprimento zero ou $Unknown. Neste caso, o servidor deve ter um serviço com o nome do serviço de NetListen, ou $Unknown para realizar o pedido.

    Nota: Se o cliente solicita um serviço que não está definido no servidor, e se houver um serviço curinga ou NetListen estiver definido, o servidor combinará o pedido do cliente com o serviço curinga.

  3. O cliente verifica se ele pode se comunicar com o servidor.
  4. Se o cliente não puder se comunicar com o servidor, um código de erro (-13) HOST_UNREACHABLE será retornado ao cliente.

  5. O servidor determina se um servidor TSD Script está atendendo na porta solicitada (ou padrão).
  6. Se um servidor TSD Script não estiver em execução, um código de erro -13 HOST_UNREACHABLE será retornado ao cliente.

  7. Se um servidor TSD Script estiver sendo executado, o servidor consulta a si próprio para determinar se a conexão entre o cliente e o servidor TSD Script já está estabelecida.
  8. Se a conexão já estiver sendo estabelecida, TRUE é retornado ao cliente. O identificador da conexão também é retornado.

  9. Se não houver conexão aberta para o serviço, o servidor TSD Script procura um gabarito com um nome de serviço que corresponda ao serviço solicitado pelo cliente e esteja associado à porta na qual o pedido foi recebido.
  10. Se for encontrado um nome de serviço correspondente, o servidor retornará um identificador ao cliente. O identificador aponta para uma cópia do gabarito que fornece o serviço. Quando o cliente retém o identificador, ele poderá continuar com seu processamento.

  11. Se não houver serviço correspondente, o servidor determinará se um gabarito com um serviço curinga foi registrado e está associado à porta na qual o pedido foi recebido.
  12. Se o servidor encontrar um serviço curinga, o servidor retornará o identificador ao cliente. O identificador aponta para uma cópia do gabarito que fornece o serviço curinga. Quando o cliente retém o identificador, ele poderá continuar com seu processamento.

  13. Se não houver gabarito com serviço curinga e o pedido foi recebido na porta padrão, o servidor verifica se há a presença de uma rotina de tratamento de eventos NetListen.
  14. Se uma rotina de tratamento de eventos NetListen for encontrada, será retornado um identificador ao cliente que descreve a conexão à máquina cliente. Se encontrada, o identificador aponta diretamente para a rotina de tratamento de eventos NetListen. Quando o cliente reter o identificador, ele continuará com o processamento dos dados do evento.

    Se uma rotina de tratamento de eventos NetListen for encontrada, vá para a etapa 10. Se uma rotina de tratamento de eventos NetListen não for encontrada, continue com a etapa 8.

  15. Se um serviço correspondente ainda não foi encontrado, o NetConnect retornará um código de erro (-16), indicando que o serviço solicitado não é suportado no servidor destinado.
  16. Se um serviço NetRegister for encontrado, uma conexão NetRegister será criada a partir do gabarito com sua própria cópia de dados de ocorrência. O identificador de eventos retém uma mensagem $MsgCreate.
  17. O servidor envia à rotina de tratamento de eventos uma mensagem $MsgNetConnect para abrir a conexão no lado do servidor.

Após $MsgNetConnect ser processado no servidor, a conexão é aberta e o serviço pode ser utilizado.

Como fechar uma conexão

O processo de fechamento de uma conexão, geralmente, é iniciado pelo cliente. Entretanto, o servidor também pode iniciar o fechamento. Neste caso, a instrução NetClose é utilizada para fechar a conexão.

Nota: Se o cliente ou o servidor forem desativados, a conexão entre eles será dissolvida. Para restabelecer a comunicação entre as máquinas, você deve reabrir a conexão.

Fechamento iniciado pelo cliente

Quando um cliente fecha uma conexão, ocorre o seguinte processo:

  1. O cliente fecha a conexão.
  2. O servidor detecta que a conexão foi fechada. O servidor responde enviando à rotina de tratamento de eventos duas mensagens:
  3. O identificador é marcado como fechado.

Nota: Se a rotina de tratamento de eventos for NetListen, não haverá dados de ocorrência especificamente definidos para a conexão. O processo de fechamento é concluído quando o identificador é marcado como fechado. Nenhuma mensagem $MsgNetDestroy é enviada.

Se o programa cliente ou servidor finalizar ou se houver uma interrupção na rede, as etapas 2 e 3 ainda ocorrerão.

Fechamento iniciado pelo servidor

Se o servidor iniciar o fechamento da conexão, não existirá nenhuma comunicação do servidor retornada ao cliente.

A próxima vez que o cliente tentar se comunicar com o servidor, detectará o fechamento e gerará uma mensagem de erro, como "identificador inválido."
Em um ambiente ponto a ponto NetClose fecha a conexão do cliente e do servidor.

Dados de Ocorrência

Dados de ocorrência são dados do TSD Script definidos pelo usuário e são associados à conexão. Os dados de ocorrência são criados quando a conexão é criada e é destruída quando a conexão é fechada.

Rotina de tratamento de eventos faz referência aos dados de ocorrência

A rotina de tratamento de eventos retém uma referência aos dados de ocorrência com cada mensagem para a conexão. Os dados de ocorrência armazenam informações específicas às conexões.

Quando você registra uma rotina de tratamento de eventos com NetRegister, é possível especificar um valor inicial para os dados de ocorrência desta rotina de tratamento de eventos. Todas as conexões que são abertas para o gabarito retêm uma cópia dos dados de ocorrência inicializados no valor especificado, ou em $Unknown caso nenhum valor inicial tenha sido fornecido.

Quando você especificar os dados de ocorrência, lembre-se do seguinte.

Por exemplo:

connectionData is Record
     callCount = INTEGER;
.
.
.
END; 
NETCONNECTION EVENT MyEvent (REF data: ConnectionData);
ACTIONS
    When $Event IS $MsgCreate Then
        data.callCount=1;
        .
        .
        . 
END;
END;
StmtData : ConnectionData;
NetRegister( MyEvent {StartDate}, 'Service');

Como inicializar os dados de ocorrência

Quando uma conexão é aberta, os dados de ocorrência definidos para a rotina de tratamento de eventos são criados a ocorrência na cópia do gabarito para a conexão e é atribuído seu valor inicial. Este processo é chamado inicialização.

Dados de ocorrência $Unknown

Se você definir o valor dos dados de ocorrência no gabarito como $Unknown, significará que a inicialização não ocorreu.

A inicialização também não ocorrerá, a menos que você defina um valor para o valor inicial dos dados de ocorrência. Se você não definir um valor, assume-se o valor inicial como $Unknown.

Múltiplas conexões para uma rotina de tratamento de eventos

Podem existir múltiplas conexões abertas para uma única rotina de tratamento de eventos NetRegister. Cada uma destas conexões tem sua própria cópia dos dados de ocorrência.

Instruções de Bloqueio e Não-Bloqueio

Um cliente pode enviar um pedido a um servidor a qualquer momento, independentemente se o servidor está atualmente no processo de manusear um pedido anterior ou não. Dependendo de quão rápido o cliente requer uma resposta do servidor, e se o cliente requer que os dados sejam retornados do servidor, ele pode enviar seu pedido com uma instrução bloquear ou não-bloquear:

Quando um servidor retém pedidos, ele os inclui na sua fila. Conforme for possível, o servidor processará os pedidos na ordem em que foram retidos. (Em alguns casos, o servidor pode colocar mensagens de bloqueio na fila, na frente das mensagens de não-bloqueio). Dependendo da condição da rede, pode levar algum tempo antes que o servidor possa executar o serviço de um pedido.

Instruções de bloqueio

Se a instrução enviada ao servidor for uma instrução de bloqueio, não será retornada nenhuma informação ao cliente até que o processo inteiro possa ser concluído no servidor.

SendMessage é a única instrução de bloqueio no TSD Script.

Para prevenir bloqueio entre um cliente e servidor, somente uma SendMessage por vez, pode estar ativa na conexão.

Instruções de não-bloqueio

Se a instrução enviada ao servidor for de não-bloqueio, o servidor retornará uma resposta ao cliente informando, "Estou com seu pedido" quando a instrução for adicionada à fila. O cliente pode, então, continuar seu processamento.

Há várias instruções de não-bloqueio:

Como escolher o tipo de instrução a ser enviada

Você pode escolher instruções de bloqueio ou não-bloqueio para se comunicar com o servidor. A escolha de um dos dois tipos implica em alguns riscos dos quais precisa estar ciente:

Identificadores

No TSD Script e no Developer's Toolkit, os identificadores são utilizados extensivamente para manter o controle da atividade da rede e da janela.

Os identificadores são necessários nas conexões com as instruções SendMessage ou PostMessage. Estas instruções são de bloqueio e não-bloqueio, respectivamente. Esta característica determina o procedimento do cliente e do servidor.

Como abrir um identificador

O servidor abre o identificador quando ele localiza o gabarito da rotina de tratamento com o serviço que corresponde ao serviço solicitado pelo cliente. O identificador está contido no parâmetro $Handle e passado ao grupo de eventos servindo a conexão.

Como fechar um identificador

O servidor marca um identificador como fechado quando o servidor fecha a extremidade da conexão. Se você tentar acessar uma conexão fechada, receberá uma mensagem de erro (Invalid_Handle).

Como Estabelecer Comunicação Bidirecional

As instruções NETx do TSD Script podem ser utilizadas nas arquiteturas cliente/servidor e ponto a ponto. Para manusear estas arquiteturas diferentes, há dois formatos para a instrução NetConnect.

Cliente/servidor

Na arquitetura de cliente/servidor, o cliente deve especificar um nome de sistema central e serviço para que o servidor possa responder ao pedido do cliente e retornar o serviço para e o servidor possa responder ao pedido do cliente e retornar o serviço solicitado.

FUNCTION NetConnect(REF hndlHost: NETCONNECTION,
                    .VAL hostName: STRING, 
                    . VAL service: STRING
                    .): INTEGER;

Ponto a Ponto

Para responder ao cliente na arquitetura ponto a ponto, o servidor deve abrir uma conexão de retorno. O formato ponto a ponto é realmente um atalho para a criação de uma conexão de retorno. Este formato é opcional; você pode atingir o mesmo resultado utilizando o formato cliente/servidor.

FUNCTION NetConnect( VAL hndlHost: NETCONNECTION
                    ): INTEGER;

Identificadores TSD Script para conexões ponto a ponto

Você precisa de apenas um identificador para uma conexão ponto a ponto. O identificador conterá todos os dados sobre a conexão.

Para obter uma descrição detalhada de NetGetHostName ou NetGetService, consulte o próximo capítulo.

Utilize a constante $Handle para enviar uma resposta para um servidor remoto. Você pode inicializar uma conexão de retorno com a seguinte linha:

NetConnect( $Handle );

Instruções Avançadas: NetListen e NetAccept

Até agora, este capítulo enfocou o método "padrão" de criação e registro de uma rotina de tratamento de eventos utilizando a instrução NetRegister. Para aplicativos que requerem mais controle sobre conexões, o TSD Script fornece um conjunto de instruções alternativo que pode ser utilizado junto com o registro de uma rotina de tratamento de eventos. Estas instruções são:

As rotinas de tratamento de eventos NetAccept são muito semelhantes às rotinas de tratamento de eventos NetRegister.

Nota: Você não tem que utilizar as instruções NetListen ou NetAccept para conseguir um aplicativo de rede completamente funcional.

Tabela de diferenças de rotina de tratamento de eventos

Esta tabela resume as diferenças entre as rotinas de tratamento de eventos NetRegister e NetListen.

Devido a NetListen não criar novos dados de ocorrência para cada conexão, o processo de abertura de uma conexão através de NetListen é um pouco mais rápido.

NetListen é bem adequado para serviços ligeiros que não requerem que um contexto seja mantido entre as mensagens.

Item de comparação NetRegister NetListen
Número de Rotinas de Tratamento de Eventos Pode existir várias rotinas de tratamento de eventos NetRegister sendo executadas em um servidor simultaneamente. Pode existir apenas uma rotina de tratamento de eventos NetListen definida para um servidor.
Serviço Registrado Uma rotina de tratamento de eventos NetRegister é registrada com um serviço específico. O cliente deve solicitar este nome de serviço exatamente para obter um serviço que corresponda ao gabarito apropriado. Uma rotina de tratamento de eventos NetListen não possui um serviço específico a ela associado. Uma correspondência de serviço é feita com a rotina de tratamento de eventos NetListen somente se não houver outros gabaritos correspondentes no servidor.
Gabarito Quando você registra uma rotina de tratamento de eventos NetRegister, é criado um gabarito dela. O gabarito contém todas as informações específicas da conexão. Não há gabarito criado quando você registra uma rotina de tratamento de eventos NetListen. As informações específicas da conexão devem ser mantidas pelo aplicativo.
Dados de Ocorrência Cada conexão tem sua própria cópia dos dados de ocorrência. Há um conjunto de dados de ocorrência definido para a rotina de tratamento de eventos. Toda conexão aberta para a rotina de tratamento de eventos compartilha estes dados de ocorrência.
Portas O serviço pode utilizar uma porta alternativa. O serviço pode utilizar apenas a porta padrão.

Utilizações das rotinas de tratamento de eventos NetListen e NetRegister

Você pode ter uma rotina de tratamento de eventos NetListen e uma NetRegister sendo executadas ao mesmo tempo em um servidor. Devido ao fato de um cliente não saber como um pedido é servido, o cliente não pode especificamente pedir qual rotina de tratamento será utilizada.

As rotinas de tratamento de eventos NetListen são utilizadas em serviços que não exigem que informações de contexto sejam mantidas em uma conexão. As rotinas de tratamento de eventos NetListen requerem um pouco menos de recursos do servidor e criam conexões um pouco mais rápido do que as rotinas de tratamento de eventos NetRegister.

O pedido do cliente corresponde a uma rotina de tratamento de eventos NetListen somente se nenhuma outra correspondência (incluindo um gabarito curinga) puder ser encontrada. O cliente envia o nome do serviço à rotina de tratamento de eventos NetListen no servidor. A rotina de tratamento de eventos NetListen deve consultar o identificador do serviço com NetGetService.

O cliente, entretanto, não possui garantias de que o serviço é suportado pelo servidor.

Conexões NetListen

Pode haver várias conexões NetListen abertas simultaneamente, desde que cada conexão compartilhe os mesmos dados de ocorrência com outras conexões abertas. Portanto, quando você fecha uma conexão NetListen, os dados de ocorrência não são destruídos.

Ao fechar uma conexão NetListen, você precisa limpar os recursos da conexão que está sendo fechada.

Identificadores

O identificador para cada conexão NetListen possui as informações sobre o tipo específico de serviço que está sendo solicitado pelo cliente.

A rotina de tratamento de eventos NetListen não associa dados de ocorrência a cada conexão. Em vez disso, você deve manter o controle de cada conexão e sua atividade. A capacidade de rastrear conexões individuais é um benefício a mais do uso da instrução NetListen para registrar rotinas de tratamento de eventos.

Como atribuir dados de ocorrência específicos para uma conexão NetListen

Cada conexão aberta para NetListen compartilha a cópia dos dados de ocorrência definidos para a rotina de tratamento de eventos NetListen. Se você deseja associar um conjunto específico de dados de ocorrência a uma de suas conexões NetListen abertas, chame a instrução NetAccept para essa conexão.

Nota: NetAccept pode ser chamada somente para uma conexão NetListen. Você acessa a conexão utilizando seu identificador. NetAccept também pode se associar a uma nova rotina de tratamento de eventos com a conexão.

Os dados de ocorrência associados à conexão não são utilizados com qualquer outra conexão que esteja atualmente aberta ou que possa ser aberta no futuro para a rotina de tratamento de eventos NetListen. Após você chamar NetAccept, a conexão será alterada.

Todos os pedidos para o mesmo par host/serviço vão diretamente para a nova rotina de tratamento de eventos.

Nota: Você pode achar mais fácil utilizar NetRegister, pois a combinação de NetListen e NetAccept atinge o mesmo resultado.

Exemplo do Programa TSD Script Talk

Este exemplo ilustra como configurar um programa de conversa simples entre dois computadores de rede. Este programa demonstra a interação entre duas máquinas em um ambiente ponto a ponto.

KNOWLEDGEBASE NetTalk; 
CONSTANTS
    menuList IS { 
      '~File',
          'e~Xit', '',
      '~Host',
          '~Open', '',
      '~Help',
          '~About', ''
   }: LIST OF STRING;
   MsgUserChar IS $MsgUser;
   MsgRemoteChar IS $MsgUser + 1;
   MsgTalkClose IS $MsgUser + 2; 
ROUTINES 
EVENT TalkMainEvent;
FUNCTION CreateTalkWindow( VAL host: NETCONNECTION ) : WINDOW;
PROCEDURE NetTalkMain; 
PRIVATE
TYPES 
    TALK_RECORD IS RECORD
        xLen: INTEGER; -- Width of window in characters 
        yLen: INTEGER; -- Height of window in characters
        whdlMe: WINDOW; -- Window where local input
                     is displayed
        whdlYou: WINDOW; -- Window where remote input 
                     is displayed
      host: NETCONNECTION; -- Handle host
END;
PANNEL_DATA IS RECORD
  whdlParent: WINDOW;
  curX: INTEGER; -- X location of cursor on the window
  curY: INTEGER; -- Y location of cursor on the window
  lines: LIST OF STRING; -- List of all lines being edited
END; 
ROUTINES 
NETCONNECTION EVENT TalkConnectEvent(REF whdl: WINDOW )IS 
VARIABLES
    result : INTEGER; 
ACTIONS
  WHEN $Event IS $MsgNetConnect THEN
  -- Create a talk window.
  -- Create a connection to service this talk session
  result := NetConnect( $Handle );
  IF result < 1 THEN
      WinMessageBox(whdl,'Error',$MBOk + $MBIconError, 
                   'Connection failed ERROR ' & result );
    Exit( 0 );
END;
  whdl := CreateTalkWindow( $handle );
  IF whdl = $UNKNOWN THEN
     WinMessageBox(whdl,'Error',$MBOk + $MBIconError, 
                  'Window creation failed' );
   NetClose( $Handle );
   Exit( 0 );
END;
ELSWHEN MsgRemoteChar THEN
  -- Pass the character from the remote machine to the
     talk window 
  SendMessage( whdl, MsgRemoteChar, $KeyCode );
ELSWHEN MsgTalkClose THEN
  NetClose( $Handle );
ELSWHEN $MsgNetClose THEN
  -- When the windows close on the remote machine
    clean up here
  SendMessage( whdl, $MsgClose );
  NetClose( $Handle );
END;
END; 
EVENT TalkMainEvent IS
VARIABLES
  host : NETCONNECTION;
  hostName : STRING;
  result : INTEGER;
ACTIONS
  WHEN $Event IS $MsgCreate THEN
    WinSetMenuBar( $Handle, menuList );
  ELSWHEN $MsgMenu THEN
    WHEN $MenuSelection IS 101 THEN
      SendMessage( $Handle, $MsgClose );
    ELSWHEN 201 THEN
        WinEditField($Desktop, hostName, 0, 0, 40,
                    'Enter host name', 
                    BitOr($WinTitle, $WinBorder, 
                         $WinAutoPos ) );
       -- Create a talk connextion to hostname
       result := NetConnect( host, hostName, 'Talk' );
    IF result <> 1 THEN
        WinMessageBox($Handle, 'Error', 
                      $MBOk + $MBIconError, 
                      'Connection failed
                      ERROR ' & result );
END;
END;
END;
END;
EVENT TalkPannelEvent( REF pannelData: PANNEL_DATA ) IS
ACTIONS
  WHEN $Event IS $MsgCreate THEN
    pannelData.curX := 1;
    pannelData.curY := 1;
    ListInsert( pannelData.lines, '' );
  ELSWHEN $MsgPaint THEN
    -- Clear window, and re display contents
   WinSetFont($Handle, 'System Monospaced', 10, 0 );
   WinClear($Handle );
   WinWriteLn($Handle, pannelData.lines );
  ELSWHEN $MsgChar THEN
     -- The parent window processes all characters
        entered
     SendMessage(pannelData.whdlParent, $MsgChar, 
                $KeyCode );
  ELSWHEN MsgUserChar THEN
    WHEN $KeyCode IS $KeyReturn THEN
      -- Enter key is a new line
      pannelData.curX := 1;
      pannelData.curY := pannelData.curY + 1;
      ListInsert(pannelData.lines, '' );
  ELSE
     -- Add character to current line, and display it
     WinSetFont($Handle, 'System Monospaced', 10, 0 );
     WinGotoXY($Handle, pannelData.curX,
               pannelData.curY );
  WinWrite($Handle, Char( $KeyCode ) );
           pannelData.curX := pannelData.curX + 1;
           pannelData.lines[ $CURRENT ] := 
             StrInsert(pannelData.lines [ $CURRENT ],
                       Char( $KeyCode ), 1000 );
END;
END;
END; 
     EVENT TalkEvent( REF talkData: TALK_RECORD ) IS
VARIABLES
       pannel : PANNEL_DATA;
       yLen : INTEGER; 
     ACTIONS
       WHEN $Event IS $MsgCreate THEN
        -- Create 2 display panels for local, and remote
           characters and pass in parent
         pannel.whdlParent := $Handle;
         yLen := talkData.yLen / 2;
         WinCreate($Handle, talkData.whdlMe,
                   TalkPannelEvent{ pannel }, 
                   0, 0, talkData.xLen, yLen, '',
                   $WinField );
         yLen := talkData.yLen - yLen;
         WinCreate($Handle, talkData.whdlYou, 
                    TalkPannelEvent{ pannel }, 
                    0, yLen + 1, talkData.xLen, yLen,'', 
                    $WinField );
   ELSWHEN $MsgDestroy THEN
      PostMessage( talkData.host, MsgTalkClose );
   ELSWHEN $MsgSize THEN
      -- Position and size panels to fit window when
         it is resized
     talkData.xLen := $EventParm( 1, INTEGER );
     talkData.yLen := $EventParm( 2, INTEGER );
     yLen := talkData.yLen / 2;
     SendMessage(talkData.whdlMe,$MsgSetSize 
                 talkData.xLen, yLen);
     yLen := talkData.yLen - yLen;
     SendMessage(talkData.whdlYou,$MsgSetSize,
                 talkData.xLen,yLen );
     SendMessage(talkData.whdlYou,$MsgMove,1,
                 yLen + 1 );
  ELSWHEN $MsgChar THEN
    -- Send local characters to top pannel for display
    SendMessage(talkData.whdlMe, MsgUserChar,
                $KeyCode );
    -- also send character to remote host to display
    PostMessage(talkData.host, MsgRemoteChar,
                $KeyCode );
  ELSWHEN MsgRemoteChar THEN
    -- Send remote character to bottom pannel for display
    SendMessage(talkData.whdlYou, MsgUserChar,
               $KeyCode );
  ELSWHEN $MsgPaint THEN
    WinClear( $Handle );
END;
END; 
FUNCTION CreateTalkWindow( VAL host : NETCONNECTION ) : WINDOW IS
VARIABLES
  whdlNetTalk: WINDOW;
  talkData: TALK_RECORD;
  result: INTEGER; 
ACTIONS
  talkData.host := host;
  result := WinCreate($Desktop, whdlNetTalk, 
                      TalkEvent{talkData},
                      0, 0, 0, 0,
                      NetGetHostName(host), 
                      BitOr($WinBorder, 
                            WinTitle,
                            $WinResize,
                            $WinSysMenu,
                            $WinAutoSize, 
                            $WinAutoPos,
                            $WinTaskList));
  IF result < 1 THEN
    WinMessageBox($Desktop, 'Error', 
                  $MBOk + $MBIconError,
                  'Cannot create talk main
                  window. 
                  Error: '&result );
END;
  EXIT( whdlNetTalk );
END; 
PROCEDURE NetTalkMain IS
VARIABLES
  whdlNetTalk: WINDOW;
  result: INTEGER; 
 ACTIONS
  result := WinCreate($Desktop, whdlNetTalk,
                      TalkMainEvent, 0, 0, 
                      40, 0,
                      'Network talk program', 
                      BitOr($WinBorder,
                            $WinTitle,
                            $WinResize,
                            $WinSysMenu,
                            $WinMenu,
                            $WinTaskList));
 IF result < 1 THEN
   WinMessageBox($Desktop, 'Error',
                 $MBOk + $MBIconError,
                 'Cannot create talk 
                 main window.
                 Error: ' &result );
END;
 NetRegister( TalkConnectEvent, 'Talk' );
 WinWait( whdlNetTalk );
END;

Tivoli Service Desk 6.0 Developer's Toolkit - Guia de Programação do Script

Retornar ao Índice

Copyright