Pular para o conteúdo principal

Projeto de sistemas distribuídos usando CORBA, parte II : Primeiros passos

1. Um pouco mais sobre o CORBA

O padrão CORBA é um framework que permite que aplicações distribuídas em uma rede (local ou mesmo na internet) comuniquem-se entre si e troquem informações. Estas aplicações podem estar sendo executadas em diferentes plataformas (Intel, Sun, etc) e sistemas operacionais (Windows, Linux, Unix, etc) e podem ter  sido construídas em diferentes linguagens de programação. 
Utilizando o padrão CORBA é possível ter aplicações completamente distribuídas, potencialmente com cada pedaço de software sendo executado em qualquer parte da rede e em qualquer plataforma, sem que o usuário perceba que isto está acontecendo e sem que o desenvolvedor precise se preocupar em criar soluções que resolvam os problemas de interoperabilidade entre os diferentes pedaços da aplicação. Atualmente, diversas ferramentas já suportam o padrão CORBA, como Delphi 4, JBuilder 2, Oracle 8i, Cold Fusion e C++ Builder. Uma grande vantagem de CORBA é ser um padrão diretamente suportado por empresas em todo o mundo e com dezenas de implementações disponíveis, incluindo algumas gratuitas. Na prática, essa padronização significa que você não precisa ficar preso a determinados fornecedores, plataformas ou produtos, como acontece quando são escolhidas soluções proprietárias.

2. ORB
A arquitetura CORBA define o ORB (Object Request Broker) como um módulo intermediário entre cliente e objeto, sendo responsável em aceitar a requisição do cliente, enviá-la para o objeto competente e, assim que disponível a resposta, entregá-la para o cliente.

3.IDL
A CORBA utiliza a IDL (Interface Definition Language), uma linguagem baseada em C++ que não possui algoritmos nem variáveis, ou seja, é puramente declarativa, e, portanto, é independente da linguagem de programação utilizada para acessá-la. Há padrão de IDL definido pelo OMG para C, C++, Java, TTCN, COBOL, Smalltalk, Ada, Lisp, Python e IDLscript. Possibilita a interoperabilidade entre os diversos sistemas, visto a separação que é definida entre interface e execução. A interface de cada objeto é definida de forma bastante específica, enquanto a sua execução (código fonte e dados) permanece oculta para o resto do sistema.

4.Primeiros passos
A primeira coisa que definimos é que já que o CORBA suporta o paradigma de orientação a objetos , vamos "enviar objetos mensagens" de uma estação para outra , isso vai tornar muito mais fácil o tratamento das mensagens quando elas chegarem nas estações , colocamos enviar objetos entre aspas porque o CORBA não faz exatamente isso, mas vamos explicar isso em momento oportuno.

Definido o formato da mensagem precisamos criar o arquivo IDL (Interface Definition Language), que vai definir como vai acontecer a troca de informação entre as estações , no nosso projeto o arquivo ficou da seguinte forma:


struct Evento{
string tipo;
long timestamp;
long origem;
long ordemEnvio;

};

interface Mensagem{

void sendMensagem(in Evento ev);


};


Nomeamos o arquivo IDL como Mensagem.idl , o objeto mensagem está espelhado na Struct Evento , como a IDL é baseada em C++  temos que usar structs quando quisermos manipular objetos , nesse caso nosso objeto será Evento  e ele terá os seguintes campos :

  • tipo: pode assumir 'e' no caso de evento interno ou 'm' no caso de mensagem sendo enviada para as outras estações.
  • timestamp :  leva o timestamp indicando o momento ( de acordo com o relógio lógico de lamport) quando o evento ocorreu .
  • origem : indica de onde está vindo a mensagem
  • ordem de envio : indica a ordem local do evento ,  1º , 2º , 3º evento a ocorrer na estação "x" e assim sucessivamente.
Para mais detalhes sobre relógios escalares de Lamport , procurar o livro : Sistemas Distribuídos conceitos e projeto - Coulouris etal . Capitulo 11 - Tempo e estados globais.

Depois de definir a struct definimos a interface Mensagem , essa interface será mapeada em diversas classes holder e stubs que mostraremos a seguir , dentro da interface temos um método abstrato sendMensagem ( in Evento ev) ... a escolha do nome do método não foi feliz na verdade ele devia ser mudado para receiveMensagem , quando analisarmos o código vai dar para ver isso melhor ... continuando o in Evento ev  significa que o método recebe um Evento  ev e que só serve para receber ou seja é um método de entrada de dados ( input ) por isso o in.

O projeto foi todo desenvolvido usando o Netbeans , então criamos um projeto java  e um pacote que chamamos de PSD ( projeto de sistemas distribuídos - olha a criatividade ai :-)  ) , depois de criar esse projeto criamos o arquivo Mensagem.idl ...

O próximo passo é usar o compilador IDL que vai ler o arquivo e gerar as classes auxiliares necessárias, para isso utilizamos o prompt de comando ou o terminal (no meu caso) , entramos na pasta que contem os arquivos e digitamos o comando: idlj -fall Mensagem.idl ( veja a figura abaixo)


O compilador IDL vai gerar todas as classes auxiliares necessárias ao projeto , veja abaixo como ficou a pasta do projeto depois da compilação do arquivo idl.





A partir do arquivo idl ( arquivo de texto ) o compilador cria a classe Evento , arquivos holder e helper além do arquivo POA e Stub , basicamente cada uma tem uma tarefa :


  • POA :  Esta classe abstrata é baseada no esqueleto do servidor. Extende org.omg.PortableServer.Servant, e implementa a interface InvokeHandler e a interface MensagemOperations. A classe de servidor, HelloServant, extende MensagemPOA
  • Holder e Helper : implementam operações necessárias a comunicação em corba .
  • Stub : é a classe responsável por serializar e deserealizar os objetos no momento da transmissão , o corba na verdade não envia objetos de uma estação para outra , ele envia um streaming de bytes que podem depois ser convertidos para objetos java , com o uso do stubs isso fica transparente para o programandor.
  • Operations :  Esta interface contém o método sendMessage() . O idlj coloca as operações definidas na interface IDL dentro este arquivo, que é compartilhado por ambos o stubs e esqueletos.

Acabou a parte fácil , agora é programar tudo no braço , muita calma nessa hora . Pela especificação do projeto precisamos de uma camada de aplicação e outra de serviços ( cliente / servidor ).

Na camada de aplicação colocamos uma classe apenas chamada PSD , ela vai ativar na camada de serviço as classes de servidor e emissor como a figura abaixo :



Acima da PSD temos a camada de GUI ( Graphical User Interface ) que foge do escopo do artigo mas que deve ser mostrada no ultimo post , na camada de servico temos as seguintes classes:

Servidor : aciona o servidor da aplicação e publica o objeto no servidor de nomes
Emissor : recebe os eventos do PSD
Relógio : implementação do relógio lógico de lamport ,  acessado tanto pela classe servant quanto pelo emissor.
Servant: esse é o servidor propriamente dito , ele vai receber as mensagens e montar o buffer de delivery das 3 estações .

5. Classe PSD ( camada de aplicação ) :

Vamos explicar essa classe parte por parte

package psd8;

import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Joao
 */
public class PSD1 implements Runnable{

    /**
     * @param args the command line arguments
     */
    
    boolean imprimiu = false;
    private ArrayList buffertmp = new ArrayList();
    ServidorMensagem servm;
    MensagemServant ms = new MensagemServant();
    private static ArrayList b1 = new ArrayList();
    private static ArrayList b2 = new ArrayList();
    private static ArrayList b3 = new ArrayList();
    private static ArrayList bufferDelivery = 
                                               new ArrayList();
    private static boolean bufferNaoMontado = true;
    private static Semaphore semBD ;
    private static boolean terminar = false;


Essa classe é o PSD1 por que tirei da implementação da estação 1 , a primeira coisa importante a dizer é que a classe implementa Runnable , isso por que ela vai funcionar como uma thread , alias esse sistema é cheio de threads o que requer muita atenção e cuidados extras , se vc não entende de threads recomento o artigo do GUJ  Introdução ao sincronismo e monitores .

A classe também tem vários arraylists b1,b2, b3 é para armazenar as mensagens que chegam das estações , essas mensagens depois vão ser usadas na camada gráfica (GUI) , a mesma coisa acontece com o bufferDelivery que é o buffer onde ocorre a montagem da ordem total de entrega das mensagens segundo os relógios lógicos , na verdade o buffer de delivery é montado na classe servant mas é acessado concorrente mente com a classe PSD , e por isso usamos a classe Semaphore , semáforo são uma das formas de se controlar o acesso concorrente de processos em uma variável no caso o buffer de montagem , isso acontece no nosso projeto por que a medida que as mensagens vão chegando o buffer de delivery é montado e a aplicação vai pegando os valores colocados no buffer , tudo concorrentemente , veja que nesse ponto o complicado não é o sistema distribuído em si mas o acesso concorrente e o uso de varias threads .

Continuando na classe PSD ...

    public void run() {
        
        this.iniciar();
        
    }
     
     
  public void iniciar( ){




Esse método run deve ser implementado em cada classe que implemente Runnable quando a thead desse processo começar a rodar é esse método run que vai rodar primeiro , no nosso programa ele chama o método iniciar ...

 
public void iniciar(){
     String[] args=null;
        
        Relogio.initRelogio();//inicia o relógio logico de Lamport
        
        //instancia um servidor que ira publicar as mensagens e criar o servant
         servm = new ServidorMensagem(args);
        Thread tservidor = new Thread(servm);
        tservidor.setName("Thread do servidor");
        tservidor.start();
            try {
                tservidor.join();
                //aguarda aqui até a thread do servidor teminar isso é necessario
                //para que não se tente rodar a thread cliente antes de registar 
                //os objetos no servidor de nomes
            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        //iniciar o montador de bufferFinal    
        ms.iniciarMontagem();    
         
        
        Emissor em = new Emissor(args);
        Thread tcliente = new Thread(em);
        tcliente.setName("Thread do cliente");
        
        tcliente.start();
            try {
                tcliente.join();
                //aguarda o cliente terminar de transmitir a mensagem

            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
        
            
         //já pronto para enviar mensagens
            
        //thread para acesso ao buffer de delivery no servant
        new Thread(new GetBufferDelivery()).start();
        
        //String _tipo, int _timestamp, int _origem, int _ordemEnvio
        
        ArrayList lista = new ArrayList();
        Evento e1 = new Evento("e",0, 1,1);
        lista.add(e1);
        Evento e2 = new Evento("m",0, 1,2);
        lista.add(e2);
        Evento e3 = new Evento("m",0, 1,3);
        lista.add(e3);
        Evento e4 = new Evento("e",0, 1,4);
        lista.add(e4);
        Evento e5 = new Evento("m",0, 1,5);
        lista.add(e5);
        Evento e6 = new Evento("m",0, 1,6);
        lista.add(e6);
        Evento e7 = new Evento("x",100, 1,7);
        lista.add(e7);
        
         //enviar eventos
        for (Evento ev : lista) {
            em.enviarMensagem(ev);
            
        }
                   
        
 }   

Inicialmente o psd inicializa o relógio lógico ( Relogio.initRelogio(); ) que deve começar com timestamp = 0 e ir avançando conforme os eventos internos e mensagens ocorrem , logo depois o psd instanciá a classe Servidor que é responsável por publicar o objeto remoto no servidor de objetos corba ( falamos dele daqui a pouco) , o servidor é instanciado atravez de uma thread , o comando tservidor.join(); obriga a thread atual aguardar a finalização da thread do servidor , isso é necessário por que logo mais vamos chamar o emissor e não podemos começar a emitir as mensagens sem que o servidor esteja "no ar ".

Depois que o servidor estiver funcionando iniciamos uma outra thread que é a thread de montagem do buffer delivery( ms.iniciarMontagem();  ) , essa thread está como uma classe interna do servant logo usamos a referencia ao servant para aciona-la  no comando:
 
O próximo passo é iniciar o emissor de mensagem( Emissor em = new Emissor(args);) , novamente em uma thread (Thread tcliente = new Thread(em); ), ele vai ter o método que possibilita o envio das mensagens . Pelo mesmo motivo do anterior fazemos um join nessa thread , isso por que o emissor deve estar funcionando para que passemos para a próxima etapa do algoritmo que é gerar e enviar os enventos , se o emissor não estiver pronto vamos gerar os eventos e na hora de enviar vai dar erro .

Depois de inicializar o emissor ( também chamado de cliente ) iniciamos uma outra thread de montagem de buffer localmente ou seja , temos uma classe interna em PSD que vai tentar acessar o buffer de delivery  conforme ele for montado e dessa forma "puxar"os valores da camada de serviço para a camada de aplicação ( new Thread(new GetBufferDelivery()).start(); ).

Nesse momento estamos com o aplicativo como a figura sugere
Como já estamos prontos para enviar as mensagens , montamos primeiramente um ArrayList com todos os evento , internos e mensagens , cada um segundo a especificação do problema, aqui cabe algumas explicações , o timestamp de cada evento esta zerado por que vai ser atualizado no momento do envio pela classe Emissor utilizando a classe Relógio . O ultimo elemento da lista é um X isso é um evento que não vai atualizar o relógio ele só é um sinalizador que a estação 1 já enviou tudo que tinha para enviar o timestamp dele é 100 para não interferir na hora de ordenar os eventos , na verdade qualquer numero alto serviria nesse caso . Finalmente o For final envia um a um os evento ao emissor , tanto os internos "e"quanto os externos "m", talvez ai a gente tenha perdido pontos no projeto já que um evento externo não precisava ser enviado só atualizado o relógio mas enviamos mesmo assim ....

O restante do código tem métodos gets e sets para as variáveis , um método que pega os semáforos usados nos buffers , um método que limpa todos os buffers ao final da operação para que a estação comece a transmitir tudo novamente, um método para desconectar do servidor de localização de objetos corba, um método utilitário que imprime os valores que estão nos buffers e  finalmente a classe interna que puxa concorrentemente os valores do buffer de delivery

  
 
public void desconectar(){
     
     servm.unbindNoServidor();
     
 }
 
 public void getSemaforos(){
    semBD = MensagemServant.getSemBD();
 }
    
    public static void insertValorB1(Evento e) {
        b1.add(e);
    }

    public static void insertValorB2(Evento e) {
      b2.add(e);
    }

    public static void insertValorB3(Evento e) {
        b3.add(e);
    }

    public static void insertValorbufferDelivery(Evento e) {
        bufferDelivery.add(e);
    }
    
   
  
//metodos para uso da Interface grafica
    public static ArrayList getB1() {
        return b1;
    }

    public static ArrayList getB2() {
        return b2;
    }

    public static ArrayList getB3() {
        return b3;
    }

    public static ArrayList getBufferDelivery() {
        return bufferDelivery;
    }

    public static boolean isBufferNaoMontado() {
        return bufferNaoMontado;
    }
    
    
    
    public static void imprimirDadosPSD(){
        System.out.println("Imprimindo buffer de Delivery no PSD!!!!!!!!");
        System.out.println("Tamanho do Buffer:"+ bufferDelivery.size() );
             for (Evento ev : bufferDelivery) {
                System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 1:");
             for (Evento ev : b1) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 2:");
             for (Evento ev : b2) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
              System.out.println("Imprimindo Buffer 3:");
             for (Evento ev : b3) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             bufferNaoMontado = false;
    }
    
    
public void limparBuffers(){
   b1.removeAll(b1);
   b2.removeAll(b2);
   b3.removeAll(b3);
   bufferDelivery.removeAll(bufferDelivery);
   bufferNaoMontado = true;
   terminar = false;
    
}



public class GetBufferDelivery implements Runnable{

        public void run() {
            getSemaforos();
            
            while(true){
                
                
                
                
          if(ms.getTamanhoBufferDelivery() != 0 ){
                     // puxar elemento por elemento
                        
                     try {
                        semBD.acquire();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
                    }    
                        
                     
                     
                       Evento e = ms.getValorNoBufferDelivery();
                       if(e.tipo.compareToIgnoreCase("x")==0){
                           terminar = true; //termina thread e nao adiciona eventos nos buffers
                       }else{
                               bufferDelivery.add(e);
                            if (e.origem == 1) {
                                b1.add(e);
                            } else if (e.origem == 2) {
                                b2.add(e);
                            } else if (e.origem == 3){
                                b3.add(e);
                            }
                       } 
                       
                       semBD.release();
                    
          }
              
          
                    if(terminar){
                        imprimirDadosPSD();
                        break;
                    }  
          
                                                     
     }//fim do while
                
                
     }


Vale a pena comentar o código da classe interna (GetBufferDelivery) , essa classe testa se o buffer de delivery no servant não está vazio , quanto não estiver vazio ela vai no servant e pega um evento no BFDelivery , claro que para isso ela aciona o semáforo correspondente para só ela conseguir acessar o BFD , cada valor puxado é adicionado no BufferDelivery local da classe PSD e também nos buffers individuais de cada emissor ( b1, b2, b3) , o processo termina quando a classe puxar um evento tipo x no BFD do servant .
Por enquanto é isso , nos próximos post vamos ver como funciona o relógio e as demais classes terminando com a classe de GUI , o código completo do PSD1 segue abaixo , até o próximo post.

CODIGO COMPLETO DA CLASSE PSD1

package psd8;

import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Joao
 */
public class PSD1 implements Runnable{

    /**
     * @param args the command line arguments
     */
    
    boolean imprimiu = false;
    private ArrayList buffertmp = new ArrayList();
    ServidorMensagem servm;
    MensagemServant ms = new MensagemServant();
    private static ArrayList b1 = new ArrayList();
    private static ArrayList b2 = new ArrayList();
    private static ArrayList b3 = new ArrayList();
    private static ArrayList bufferDelivery = new ArrayList();
    private static boolean bufferNaoMontado = true;
    private static Semaphore semBD ;
    private static boolean terminar = false;
    

     
     
     
     
    public void run() {
        
        this.iniciar();
        
    }
     
     
 public void iniciar(){
     String[] args=null;
        
        Relogio.initRelogio();//inicia o relogio logico de Lamport
        
        
         servm = new ServidorMensagem(args);
        Thread tservidor = new Thread(servm);
        tservidor.setName("Thread do servidor");
        tservidor.start();
            try {
                tservidor.join();
                //aguarda aqui até a thread do servidor teminar isso é necessario
                //para que não se tente rodar a thread cliente antes de registar 
                //os objetos no servidor de nomes
            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        //iniciar o montador de bufferFinal    
        ms.iniciarMontagem();    
         
        
        Emissor em = new Emissor(args);
        Thread tcliente = new Thread(em);
        tcliente.setName("Thread do cliente");
        
        tcliente.start();
            try {
                tcliente.join();
                //aguarda o cliente terminar de transmitir a mensagem

            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
        
            
         //já pronto para enviar mensagens
            
        //thread para acesso ao buffer de delivery no servant
        new Thread(new GetBufferDelivery()).start();
        
        //String _tipo, int _timestamp, int _origem, int _ordemEnvio
        
        ArrayList lista = new ArrayList();
        Evento e1 = new Evento("e",0, 1,1);
        lista.add(e1);
        Evento e2 = new Evento("m",0, 1,2);
        lista.add(e2);
        Evento e3 = new Evento("m",0, 1,3);
        lista.add(e3);
        Evento e4 = new Evento("e",0, 1,4);
        lista.add(e4);
        Evento e5 = new Evento("m",0, 1,5);
        lista.add(e5);
        Evento e6 = new Evento("m",0, 1,6);
        lista.add(e6);
        Evento e7 = new Evento("x",100, 1,7);
        lista.add(e7);
        
         //enviar eventos
        for (Evento ev : lista) {
            em.enviarMensagem(ev);
            
        }
                   
        
 }   
    


  
 public void desconectar(){
     
     servm.unbindNoServidor();
     
 }
 
 public void getSemaforos(){
    semBD = MensagemServant.getSemBD();
 }
    
    public static void insertValorB1(Evento e) {
        b1.add(e);
    }

    public static void insertValorB2(Evento e) {
      b2.add(e);
    }

    public static void insertValorB3(Evento e) {
        b3.add(e);
    }

    public static void insertValorbufferDelivery(Evento e) {
        bufferDelivery.add(e);
    }
    
   
  
//metodos para uso da Interface grafica
    public static ArrayList getB1() {
        return b1;
    }

    public static ArrayList getB2() {
        return b2;
    }

    public static ArrayList getB3() {
        return b3;
    }

    public static ArrayList getBufferDelivery() {
        return bufferDelivery;
    }

    public static boolean isBufferNaoMontado() {
        return bufferNaoMontado;
    }
    
    
    
    public static void imprimirDadosPSD(){
        System.out.println("Imprimindo buffer de Delivery no PSD!!!!!!!!");
        System.out.println("Tamanho do Buffer:"+ bufferDelivery.size() );
             for (Evento ev : bufferDelivery) {
                System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 1:");
             for (Evento ev : b1) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 2:");
             for (Evento ev : b2) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
              System.out.println("Imprimindo Buffer 3:");
             for (Evento ev : b3) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             bufferNaoMontado = false;
    }
    
    
public void limparBuffers(){
   b1.removeAll(b1);
   b2.removeAll(b2);
   b3.removeAll(b3);
   bufferDelivery.removeAll(bufferDelivery);
   bufferNaoMontado = true;
   terminar = false;
    
}



public class GetBufferDelivery implements Runnable{

        public void run() {
            getSemaforos();
            
            while(true){
                
                
                
                
          if(ms.getTamanhoBufferDelivery() != 0 ){
                     // puxar elemento por elemento
                        
                     try {
                        semBD.acquire();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
                    }    
                        
                     
                     
                       Evento e = ms.getValorNoBufferDelivery();
                       if(e.tipo.compareToIgnoreCase("x")==0){
                           terminar = true; //termina thread e nao adiciona eventos nos buffers
                       }else{
                               bufferDelivery.add(e);
                            if (e.origem == 1) {
                                b1.add(e);
                            } else if (e.origem == 2) {
                                b2.add(e);
                            } else if (e.origem == 3){
                                b3.add(e);
                            }
                       } 
                       
                       semBD.release();
                    
          }
              
          
                    if(terminar){
                        imprimirDadosPSD();
                        break;
                    }  
          
                                                     
     }//fim do while
                
                
     }
            
}
    
}







Comentários

Postar um comentário

Ajude o blog a melhorar comente!!!

Postagens mais visitadas deste blog

Projetos em Sala de aula

A educação baseada em projetos vem sendo usada como uma metodologia poderosa para melhor preparar estudantes do século 21, já que leva os alunos a trabalhar em conjunto, se organizar, pesquisar e executar harmonicamente. Porém, antes de levar a metodologia para a sala de aula, será que os professores sabem como e quais projetos trabalhar em suas disciplinas? Uma dessas novidades é o  PBLU (Project Based Learning University ), plataforma gratuita que ajuda a capacitar professores para o uso de projetos em suas disciplinas, como uma forma de agregar conteúdo e motivar os estudantes. Conheça os oito pontos principais para um bom programa de aprendizagem baseada em projeto: Ter conteúdo relevante.   O objetivo da abordagem é trabalhar os conceitos-chave das disciplinas acadêmicas a partir de um projeto. Desenvolver habilidades para o século 21.   Ao longo do projeto, os alunos deverão buscar uma resposta a um problema. Para isso, eles deverão buscar referências...

Video Aulas de Java já disponíveis no 4Shared

Turma segue as video aulas já disponíveis para download no 4Shared , espero que vocês gostem das aulas e por favor postem um comentario no blog dizendo o que vc's acharam preciso desse feed back para o constante aprimoramento das aulas . Basta escolher o arquivo clickar  no link para download ( tenha paciencia os arquivos são grandes ) <p>&lt;p&gt;&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;gt;se&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;&lt;/p&gt;</p> Se a Janela de Download acima não funcionar tente acessar os arquivos usando o seguinte link http://www.4shared.com/dir/34812571/bf01348d/VideoAulas.html Bom estudo  :-)

Sistemas distribuidos: Enviando mensagens TCP Parte II - Servidor

Igual ao servidor UDP esse servidor só vai receber a mensagem e envia-la de volta , ou seja é um servidor de ECO mas com boa vontade basta fazer algumas alterações que vc tem um servidor de chat :-) . Server TCP: import java.net.*; import java.io.*; public class TCPServer { public static void main(String[] args) { try { int serverPort = 7896; ServerSocket listenSocket = new ServerSocket(serverPort); //socket de escuta o socket que vai atender as requisições while(true){ Socket client = listenSocket.accept( ); Connection c = new Connection(client); //precisamos criar a classe conection que vai //inicializar nossas threads para atender a cada requisição } } catch (IOException e) { System.out.println("Listem :" + e.getMessage( )); } }//fim do main }//fim da classe Depois de fin...