quarta-feira, 30 de abril de 2008

[Aspie] Colaboração: Guia de Sobrevivência para Portadores da Síndrome de Asperger

Eis uma excelente notícia! O portal universo autista deixou disponível hoje o material produzido no post anterior. É edificante poder ajudar a disseminar esse conhecimento. Fico realmente muito feliz com isso! Novamente fica a chamada para a divulgação do material [PDF] [DOC] (de forma a que o conhecimento cheque a quem pecisa).

domingo, 27 de abril de 2008

[Aspie] Guia de sobrevivência para portadores da síndrome de Asperger

A Simone está com um aluno Asperger na sala. Dai me sensibilizei e gastei a tarde traduzindo o guia da sobrevivência para portadores de Asperger do Marc Segar.

Valeu a pena porque ficou bom! Tomei a liberdade de acrescentar algo por minha conta, do pouco que aprendi da vida. Fico muito feliz de poder ajudar um menino de 9 anos. A Simone vai imprimir e deixar disponível (sem forçar). Vejamos se ele se interessa! Eu sei que foi feito com todo o carinho!




Por favor, distribuam amplamente este material [PDF] [DOC].



Ele contêm um legado muito importante e pode ajudar muitas pessoas. Se eu tivesse tido acesso a essa informação quando criança, minha vida tinha sido muito mais fácil.

[Música] Amor em pedaços

Eis mais um vídeo em homenagem ao "antológico" Porque Neuma! No caso, desta música eu não participei (é uma pena!). Foi composta pelo Paulo e o Alex em Belo Horizonte, após a diáspora da banda!!! Fica uma homenagem a nova fase de todos. hehehehehe... [enjoy!]




Amor em Pedaços

Ouro, prataria, teus colares espalhados,
espelho partido, teu pulso ferido.
Teu corpo caido ao lado.
Um sentimento infantil de que nada...
Nada faz sentido!

Teu desespero foi, e ainda é,
ter que se agarrar a quem fingiu
E como um fantasma, passou pela parede.
E tu... Tu quebraste a cara!

E se cantasses um prece, ah...
E se os anjos te alçassem alto, alto...
E se tocasse o telefone o que dirias?

Pois quem semeia vento há que colher poeiras.
Jogar-se do precipício nunca vale a pena.
Nós somos frágeis mas ainda temos chance.
Você pediu uma canção, pois agora dançe!

E se cantasses um prece, ah...
E se os anjos te alçassem alto, alto...
E se tocasse o telefone o que dirias?


(eu te amo!)



Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Alex "Brasil" e Flávio Mateus

Ademais:

Lembrem-se, Ginger Rogers fez tudo Fred Astaire fez, mas para trás e de salto alto.
Faith Whittlesey

sábado, 26 de abril de 2008

[Opinião] Criacionismo e intolerância religiosa

Este post é decorrente da inquietude em mim gerada por um vídeo enviado por um amigo, apresentado abaixo.



O vídeo, muito bem produzido por sinal, apresenta a ciência (em particular, a teoria da evolução das espécies de Darwin) como opressora e inflexível a opniões divergentes (em particular, ao criacionismo defendido por católicos evangélicos). Nele, a "era da ciência" e a "era das máquinas" são vistas como tiranos que deve ser combatidos pois acarretarão no fim das religiões e da liberdade. Neste escopo, o autor questiona o "fato" de que os PhDs devem ser ouvidos cegamente, e qualquer opnião diversa deve ser excluída! A grande questão aqui é que o vídeo (além do fato de estar em inglês) é bem feito e tem potencial para gerar desinformação.

Não é estranho de se imaginar que tal vídeo tenha relação com a opnião expressa por este outro criacionista, que defende o dogma da criação do homem ao referenciar o pensamento crítico por "síndrome de lúcifer", com citações bíblicas inclusive.

Neste contexto, sou um PhD em engenharia biomédica, logo um dos famigerados "opressores". Dentre as minhas atividades, nos últimos 3 semestres chequei a orientar a incrível soma de cerca de 100 monografias de trabalhos de conclusão de curso em nível superior (fora o trabalho, aulas e demais orientados). Algo que me marcou foi que realmente pude passar os fundamentos do método científico para muitas pessoas (algo que realmente só se constroi ao realizar um trabalho científico) e percebi claramente a modificação do seu pensamento: fixou-se a importância do questionamento e da fiabilidade da informação. Estas pessoas vão levar tais princípios para suas vidas!

Afinal, dentre outras coisas, um dos fundamentos da ciência é o método socrático! Tal príncipio discute a descontrução do pensamento mítico pela ironia, e a indução da razão pelo questionamento e diálogo como caminho para a verdade.

Neste contexto, Sócrates discute que deve-se, de forma não ofensiva, mostrar ao interlocutor o absurdo de suas idéias evidenciando as contradições e incoerências lógicas do discurso através do diálogo aberto (exatamente o oposto sugerido pelo vídeo, que mostra a ciência como intolerante). Desta forma, a ironia (i.e. evidenciamento das contradições) é um instrumento para a construção de idéias livres de presupostos superficiais ou preconceitos.

Na discursão sobre criacionismo e a teoria da evolução das espécies, argumenta-se:

1) Não existem evidências materiais da criação divina defendida pela teologia judaico-cristã (ou por qualquer outra tradição religiosa), apenas os escritos antigos.

2) A evolução e a abiogênese são apoiados em evidências:

  • Bioquímicas: o surgimento da vida a partir da matéria inanimada (abiogênese) expressa na Hipótese Oparin-Haldane ou Hipótese Heterotrófica é comprovada pelo experimento de Urey-Miller de 1953.
  • Arqueológicas: a evolução das espécies é evidenciada pela existência dos fosséis, objeto de estudo da palenteologia (lembra dos dinossauros em Jurasic Park?!). Quanto à origem das espécies e do homem em particular, todos os processos de avaliação da idade dos fósseis tanto animais como do próprio homem e de seus precursores mais imediatos apontam números totalmente incompatíveis com os fixados pelos textos religiosos.
  • Genéticas: a evolução das espécies é evidenciada pela existência da mutação do DNA e pela seleção natural de genes, comprovada pelos estudos de Ronald Fisher (que desenvolveu a linguagem matemática e a seleção natural nos termos essenciais dos processos genéticos), J. B. S. Haldane (que introduziu o conceito de "custo" da seleção natural), Sewall Wright (que elucidou a natureza da seleção e da adaptação), Theodosius Dobzhansky (que estabeleceu a idéia de que mutações, ao criarem diversidade genética, supriam o material bruto para a seleção natural), William Hamilton (que concebeu a seleção parentada), Ernst Mayr (que reconheceu a importância chave do isolamento reprodutivo para a especiação). Tais estudos são verificáveis nos contextos de genética de populações, biologia celular, botânica, zoologia, sociobiologia e ecologia.
  • Computacionais: a evolução das espécies é evidenciada pelas soluções evolutivas, em particular aos algoritmos genéticos. Pessoalmente, acho que nada mais visual neste sentido do que o projeto golem (excelente para leigos!).
  • Antropológicas e sociológicas: pelos mecanismos de seleção artificial em populações para aptidão econômica e social, demonstrando matemáticamente causas genéticas para comportamentos como seleção consangüínea (kin selection), altruísmo, especiação e os memes. Esta nova área do conhecimento vêm sendo referida por sociobiologia (portal). Um dos ramos interessantes desta linha de pesquisa é a psicologia evolutiva.
  • Biológicas: Sua aplicação pode ser observada em diversos processos, particularmente de forma mais evidente na cladística e na a biologia do desenvolvimento (i.e. estudo do desenvolvimento embrionário).
  • Matemáticas e econômicas: A seleção natural é aplicada nos mecanismos de equilíbrio econômico (teoria da escolha racional), baseados na teoria dos jogos. A teoria dos jogos, fundamentada nos matemáticos e economistas John von Neumann e Oskar Morgenstern e que também inclui as contribuições de John Harsanyi, John Nash, Howard Raiffa, Thomas C. Schelling e Herbert Simon. Esta formulação também tem aplicações em filosofia e ciência política, ética e jornalismo.
  • Cosmológicas e geológicas: Embora não relacionadas com a evolução, a cosmologia, astrofísica e geologia também atestam pela inveracidade científica do mito de criação do universo pela teologia judaico-cristã (na qual se insere a criação divina da vida e da própria espécie humana), assumindo seu início pelo Big Bang.
Desta forma, a negação da evolução envolve a recusa em aceitar uma boa parte das ciências naturais, principalmente as descrições da história do planeta e da vida.

Dentre as hipotéses (1) e (2) reina uma questão de bom senso (assim como assumido pela navalha de Ockham)!

A recente discussão do criacionismo por grupos evangélicos é decorrente da estratégia da cunha (ao qual se insere o vídeo motivador deste post), defendendo o criacionismo pelo design inteligente, que consiste de uma pseudo-ciência (classifica-se como pseudo-ciência por não apresentar evidências materiais ou seguir o método científico). Especula-se que este movimento faça parte de uma estratégia política de grupos conservadores norte-americanos (particularmente do sul dos Estados Unidos), obtendo favorecimento eleitoral ao subsidiar a agenda social conservadora em uma ampla gama de assuntos defendidos por grupos evangélicos incluindo aborto, eutanásia, sexualidade e outros movimentos de reforma social.

Neste ponto, não tanto como pesquisador (acho que o tal título de D.Sc. me concede tal denominação), mas como humanista e cidadão consciente (de visão liberal e social-democrática) me vejo na obrigação de desmistificar e desconstruir a desinformação causada pelos dogmas criacionistas e do design inteligente, ainda mais tendo em vista a implicação política e social implícita. No Brasil, o problema não é menos sério, conforme o post anterior.

Neste ponto, me insurjo em convocar as demais pessoas de bom senso, que acreditem na humanidade, a empregar esforços para conter a intolerância e fundamentalismo religioso sempre que o mesmos:
  • Ameaçem as liberdades democráticas: e.g. discriminação ou resarciamento da liberdade de crença contra praticantes de cambomblé por grupos evangélicos pentecostais;
  • Incitem a violência, o preconceito e a intolerância: e.g. conflito palestino, etc;
  • Impuserem a exploração social/econômica do indivíduo ou a perda de sua qualidade de vida em proveito evidente de terceiros: e.g. instituições que induzem doações ou cobram dízimos - principalmente de pessoas com um salário ou menos - sem apresentar prestações de contas abertas e públicas (demostrativos de usos e fontes) que mostrem claramente o uso do dinheiro - Igreja Universal, Assembléia de Deus, etc.
  • Travestirem informações como científicas de forma a obter credibilidade: e.g. espiritismo, design inteligente/criacionismo, cientologia, noergologia, homeopatia, astrologia, radioestesia, e demais pseudociências esotéricas. Note que este problema assume uma dimensão muito mais preocupante na medida em que tais "áreas do conhecimento" alcançam o ensino superior formal, com o apoio do estado inclusive.
  • Incidam na separação entre estado e igreja: e.g. pressão contra pesquisa de células tronco no Brasil.

No entanto, cabe discutir que deve-se haver um total respeito pela liberdade de crença e o livre arbítrio em qualquer situação, cabendo apenas a intervenção e esclarecimento sobre aspectos negativos do fundamentalismo religioso (principalmente nos contextos descritos acima). Desta forma, a conclusão sobre o tema a ser discutida com os criacionistas supracitados deve serguir um formato geral semelhante a:


"Você tem todo o direito de ter suas crenças e não pretendo contestá-las! Você pode acreditar em Deus e que o mesmo criou o homem se assim o quiser, mas deve concordar que isto claramente não é uma verdade científica! Sua aceitação destes dogmas baseia-se apenas em sua fé, e não na lógica e nos fatos. As evidências mostram que a evolução das espécies é real e a vida se originou pela abiogênese. É possível crer em Deus e entender a ciência, desde que não se tente misturá-los ou conflitá-los e que não se obrigem terceiros aos dogmas, especialmente terceiros de outras crenças. A crença em Deus é uma verdade pessoal (cada um tem o seu) e a ciência é uma verdade universal (a natureza é a mesma para todos)!"


Observe-se um ponto fundamental no discurso acima: a sutileza e a não ofensividade. Deve-se sempre evitar a negação simples e direta do dogma, pois o bloqueio emocional (que normalmente acontece em conflitos diretos) dificulta, ou mesmo impede, o pensamento crítico. Desta forma, a apresentação das inevitáveis contradições do dogma sobre a lógica racional deve seguir uma linha de discurso sutil, polida e bem construída (nunca ofensiva ou destrutiva).

Note que a questão aqui não é o absurdo das idéais prosposta pelos dogmas dos fundamentalistas religiosos, mas o sequinte exercício: "Como você poderia abordar estes indivídios, de forma delicada, a fim de desconstruir sua desinformação (minimizando seu o estrago) e ainda incutir nessas pessoas o pensamento crítico?". Note que o exercício desta dialética é realmente muito difícil!

Finalmente, vale lembrar que a própria existência das religiões, e do próprio comportamento social humano, é decorrente de mecanismos genéticos e da seleção natural, ou seja, não cabe a ciência a sua destruição, uma vez que é um processo natural em si, mas o seu esclarecimento e conciliação para fins de evolução do conhecimento e da própria humanidade.

quinta-feira, 24 de abril de 2008

[Artigo] A pseudociência nas universidades brasileiras

Eis um excelente artigo que, apesar de carente de citação, traz a tona uma questão de suma importância: a legitimação da pseudociência no país.

REIS, W.P., "A Pseudociência nas Universidades Brasileiras", Proceedings of Ibero-American Conference on Critical Thinking, Buenos Aires, 2005.

Read this doc on Scribd: A pseudociência nas universidades


O autor colabora com o Projeto Ockham e o blog "Dragão da Garagem", com excelentes discursões sobre pensamento crítico.

Particularmente, recomendo o último post "o problema das virgens" em que o mesmo autor discute a "questão das 27 virgens no paraíso mulçumano", trazendo uma pespectiva etimológica inusitada para a questão.

sexta-feira, 18 de abril de 2008

[Música] A última dança

Eis uma pérola do tempos da república! Como estou "de molho" estes dias, acabei por fazer esta pequena colagem no movie maker com alguns vídeos do youtube! Para o bom saudosismo de todos! Muita depressão e melancolia numa melodia simplesmente delicada (cortesia dos gênios Paulo e Alex). Grande abraço a todos e muitas saudades! [enjoy!]





A última dança

Os olhos da morte fitaram os meus de tao perto...
Eu fiquei sem jeito...
Toquei nos lábios dela com o dedo do silêncio.
Ao toque de lábios tão frios
Bailamos pela noite adentro
E de tão perdido, no vazio,
eu esqueci do tempo
E dos resquícios de vida que ainda havia em mim. . .
havia em mim. . .
havia em mim. . .
havia em mim. . .


Bailando com a morte no salão do mundo
Eu perco a vida de vista e me Afundo. . .
E me Afundo. . .
E me Afundo. . .

Letras: Paulo Rocha
Música: Alex "Brasil"
Arranjo: Porque Neuma!
Disco: A pergunta que não quer calar (2001) [independente]







sábado, 12 de abril de 2008

[Pessoal] Assim caminha a humanidade?

Eis um fato curioso. Fui a praia. Algumas vezes até.

Fui a praia. Banal por demais até.

Parece até poesia, mas não é.

Na areia haviam parasitas, onde enfiei meu pé.

Pois os parasitas (se chamavam "larvas migrans") infectaram a pele de bactérias, dai meu pé inchou no domingo passado (se chama "celulite": pra mim isso era coisa de perna de mulher, mas parece que é mais sério que isso). Fui no hospital e lá fiquei: foi internação na hora, pois a tal "celulite" pode evoluir para uma infecção generalizada (se chama "sepsis", e tem muita gente que morre disso!) e assim estive no Hospital São Mateus essa semana inteira (i.e. 5 dias com 2 antibióticos na veia). A dose era tão alta que me deixava grogue (eu não sabia que antibióticos faziam isso). Hoje tive alta (graças a Deus, pois não ia suportar outra punção na veia: tenho trauma disso e morro de medo - de tremer todo e bater os dentes - e pra piorar tive uma flebite de leve, mas esse foi o "açucar" desse caldo! Meu medo é da agulha! hehehehehe...).


A cima e ao lado seguem fotos tiradas já em casa, hoje de manhã, do meu pé "novo de novo" (acredite: está MUITO melhor). Em verdade, o perigo maior já passou (i.e. dessa eu não morro), mas como dá pra imaginar ainda vou ficar mais uns 15 dias literalmente "com o pé pra cima". Pior que até já desencanei e não estou ansioso com isso. Creio ser isto o mais importante dada a inevitabilidade do mundo (i.e. "relaxa e goza" hehehhee...).

Ademais, não produzi nada (nem fiz nada interessante) no hospital, pois a sonolência da medicação, o desamparo do desconhecimento da data de alta hospitalar e a "sombra constante" de novas punções na veia, meio que me desmotivaram (como dizia meu velho, "não tinha élan"*). Assim a única coisa que tenho para falar hoje é da minha própria história. hehehehehe... E sendo esta uma história, há de haver uma moral (ou várias morais, pois nenhuma é, em absoluto, absoluta...):
  • Use botas "sete léguas" na praia (ou pelo menos não enterre o pé na areia - o que era um discreto costume meu, enquanto tomava um cervejinha na praia - uma "viagem" do tipo "contato com a terra, com a natureza, etc.").
  • Não leve o cachorro para a praia, oh FDP! Ou pelo menos recolha os produtos finais!
  • Eu sou um "cara de sorte"! :D

Bem, parece que assim caminha a humanidade! Menos eu, que por enquanto, não vou a lugar algum! hehehehhehe...

* Uma pesquisa rápida na wikipédia esclarece que "élan vital" ou "força vital" foi uma teoria equivocada para a evolução, do começo do século passado, que atribuia a vida a um fluído mítico - sendo a base de inspiração para a "força" de Star Wars. Esperar o que do velhão: ele chama "cinema" de "cinemascope"! Falando nisso ele me trouxe umas muletas para usar esses dias. Brigadão pai, não sei o que faria sem você. Te amo!

sábado, 5 de abril de 2008

[Livro] Contos plausíveis


Segundo João Cabral de Melo Neto, "Carlos Drummond de Andrade mostra que ser poeta não significava ser sonhador, e que a ironia e a prosa cabem dentro da poesia". De acordo!

Este livro é realmente inusitado! Antes de mais nada, porque me foi emprestado pela Ana "da elétrica" ("da elétrica" não porque a ela fosse hiperativa, mas porque cursamos engenharia juntos na boa e velha universidade estadual de Campinas! Bons tempos!!!!) que reencontrei depois de muitos anos.

Mas o livro também "faz por onde". São contos curtos e independentes: cada um com menos de uma página (um chega a ter 3 linhas). Perfeito para quem não tem saco de ler textos longos! São extremamente divertidos, onde cada final garante uma boa risada. O texto exercita de forma primorosa dois princípios básicos: simplicidade e lógica (no meu entender, duas das grandes virtudes universais). Deveria ser usado nas escolas para ensinar redação e bom senso (isso se ensina?).

Verdade seja dia: o escencial é que me diverti demais lendo esse livro, o que foi um problema pois acabou quase imediatamente, me deixando "orfão". A grande "sacada" vem por conta de uma implícita crítica irônica à pretensão literária, com finais perfeitamente lógicos à situações fantasiosas (dái o nome contos plausíveis). Desta forma, clichês são satirizados com um final comum, gerando uma surpresa e uma boa risada. Na verdade, a identificação com o livro foi tão grande, em seu culto a simplicidade e racionalidade (i.e. simplicity is beautiful), que perguntei ao bom e velho google se o Drummond não era engenheiro. Mas era farmacêutico!

Para dar o gostinho, eis um conto plausível "pseudo-aleatório":


Abotoaduras


O maior fabricante de abotoaduras de punho fechou a indústria depois de convencer-se de que é infinitamente reduzido o número de camisas de manga comprida à disposição da humanidade. E, mais, que os exemplares deste gênero, ainda existentes, são providos de botões, dispensando abotoaduras.


– Trabalhei a vida inteira no setor – lastimava-se – e almejava legar a meus filhos a tradição das abotoaduras de punho, como requinte terminal de uma camisa digna desse nome. Os fatos ergueram-se contra mim. Não posso mais produzir abotoaduras de punho para camisas sem punho ou de punho abastardado por míseros botões de plástico.


Concluiu que é o fim da civilização e ia enforcar-se numa camisa esporte, estampada, quando esta, movida por vento súbito, saiu pelos ares, qual bandeira solta. E era tão bonito o esvoaçar do pano bigarreado, tão graciosas as evoluções que o homem resolveu desistir da morte e aplicar sua fortuna em uma indústria colossal de camisas de manga curta.

quinta-feira, 3 de abril de 2008

[.NET] Comunicador simples com .NET remoting


Os componentes das APIs .Net Remoting e Java RMI (Remote Method Invocation) provêm funcionalidades para desenvolvimento de sistemas distribuídos, permitindo a chamada remota de procedimentos (i.e. de forma semelhante à RPC, no entanto, sobre o paradigma OO). Neste contexo, os métodos invocados podem ser de processos distindos na mesma estação ou em estações diversas (i.e. máquinas virtuais distintas).

Tal tecnologia também é fundamental para a integração de sistemas, sendo um alternativa aos webservices em contextos onde a performance é crítica. De forma geral, a grande vantagem sobre um implementação a nível de sockets é que se dispensa o desenvolvimento de todo um protocolo de comunicação.
Para o desenvolvimento de uma aplicação cliente-servidor sobre estas APIs, deve-se definir a interface de serviços a serem oferecidos pelo objeto servidor. Os serviços especificados pela interface remota deverão ser implementados através de classes concretas. Com a interface estabelecida e o serviço implementado, é finalmente possível criar as aplicações cliente e servidor, sendo necessário apenas o registro do serviço para que as APIs citadas encapsulem toda a serialização e transferências das mensagens.

Neste artigo apresenta-se uma aplicação "chat" simples sobre a API .Net Remoting da plataforma .NET 2.0, onde diversos clientes contectam-se a um servidor para enviar mensagens aos outros participantes. Desta forma, a solução será dividada em 3 projetos:
  • assembly "MessagerCore" (DLL): contendo toda a lógica da aplicação.

  • aplicação console "MessagerServer": com responsabilidade de ser o mediador de mensagens e servidor da aplicação .Net Remoting

  • aplicação Windows Forms "MessagerClient": com responsabilidade de interface dos usuários e cliente .Net Remoting
Neste aspecto, inicia-se pelo desenvolvimento do assembly "MessagerCore" (DLL), através da definição das interfaces do serviço. Foram definidas as interfaces IChatter (representa o usuário cliente do chat) e IChatServer (representa o mediador de mensagens). Na interface IChatter, o método MessageArrived(string message) dispara o evento IncomingMessage para tratamento no cliente.

Interface IChatter
namespace net.jorgealbuquerque.Messager.Core
{
public interface IChatter
{
// Recupera o nome do usuário do chat
string Name { get; }
// Dispara o evento IncomingMessage para tratamento no cliente
void MessageArrived(string message);
}
}

Na interface IChatServer, os métodos RegisterChatter e UnRegisterChatter registram, respectivamente, o ingresso e abandono do cliente no chat. Por sua vez, o método AddMessage(IChatter sender, string message) representa o envio da mensagem.

Interface IChatServer
namespace net.jorgealbuquerque.Messager.Core
{
public interface IChatServer
{
// Ingressa no chat
void RegisterChatter(IChatter chatter);
// Abandona o chat
void UnRegisterChatter(IChatter chatter);
// Envia mensagem
void AddMessage(IChatter sender, string message);
}
}
Uma vez definidas as interfaces do serviço remoto, pode-se construir suas classes concretas. Nestes contexto, a classe Chatter (realização de IChatter) poderia ser implementada na assembly cliente e a classe ChatServer (realização de IChatServer) poderia ser implementada no servidor. No entanto, foi realizada a opção de manter toda a lógica no assembly "MessagerCore", de forma a prover apenas lógica de apresentação nas aplicações cliente e servidor. Tal escolha quebra um pouco as o design pattern observer, mas separa eficientemetne as camadas de negócios e apresentação. Observe, no entanto, que não existe nenhuma dependência entre os namespaces do cliente e servidor.

A classe Chatter estende MarshalByRefObject, o que permite a sua serialização e manipulação remota pela API .NET remoting. Note ainda que o método MessageArrived(string message) ativa o evento IncomingMessage.

Classe Chatter
using System;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Core;
namespace net.jorgealbuquerque.Messager.Client
{
public class Chatter : MarshalByRefObject, IChatter
{
public Chatter(string name)
{
_Name = name;
}
public event IncomingMessageEventHandler IncomingMessage;
public delegate void IncomingMessageEventHandler(string Message);
private string _Name;
public string Name
{
get { return _Name; }
}
public void MessageArrived(string message)
{
if (this.IncomingMessage != null)
this.IncomingMessage(message);
}
}
}


De forma semelhante, o servidor também estende MarshalByRefObject. Neste contexto, o método UpdateObsevers(string message) realiza a atualização de todos os clientes, segundo o design pattern observer, por meio do evento IncomingMessage.


Classe ChatServer
using System;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Core;
using System.Collections.Generic;
namespace net.jorgealbuquerque.Messager.Server
{
public class ChatServer : MarshalByRefObject, IChatServer
{
private List _Chatters = new List();
public override object InitializeLifetimeService()
{
return null;
}
private void UpdateObsevers(string message)
{
foreach (IChatter observer in _Chatters)
observer.MessageArrived(message);
//Console.WriteLine(message);
}
public void AddMessage(IChatter chatter, string message)
{
if (string.IsNullOrEmpty(message))
return;
UpdateObsevers(string.Format("{0}) {1} disse: {2}",
DateTime.Now.ToLongTimeString(),
chatter.Name, message));
}
public void RegisterChatter(IChatter chatter)
{
_Chatters.Add(chatter);
UpdateObsevers(
string.Format("{0}) Usuário {1} entrou.",
DateTime.Now.ToLongTimeString(), chatter.Name));
}
public void UnRegisterChatter(IChatter chatter)
{
_Chatters.Remove(chatter);
UpdateObsevers(
string.Format("{0}) Usuário {1} saiu.",
DateTime.Now.ToLongTimeString(), chatter.Name));
}
}
}
Finalmente, a lógica de registro e conexão dos servidor e cliente foram encapsulados nas classes de serviço abaixo. A classe ServerChannelService apresenta registro para intanciação remota do ChatServer como Singleton (i.e. apenas um mediator para todos os clientes). Por sua vez, a classe ClienteChannelService mostra a chamada remota propriamente dita da mesma classe pela construção Activator.GetObject().

Classe ServerChannelService
using System;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Core;
namespace net.jorgealbuquerque.Messager.Server
{
public class ServerChannelService
{
public ServerChannelService(int port)
{
new RemotingTcpServicesHelper().ServerRegisterChannel("ChatServer", port);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ChatServer), "ChatServer", WellKnownObjectMode.Singleton);
}
}
}


Classe ClientChannelService
using System;
using net.jorgealbuquerque.Messager.Core;
namespace net.jorgealbuquerque.Messager.Client
{
public class ClientChannelService
{
IChatServer _ChatServer = null;
public ClientChannelService(string url, int port)
{
new RemotingTcpServicesHelper().ClientRegisterChannel("ChatServer", port);
string uri = string.Format("tcp://{0}:{1}/ChatServer", url, port);
_ChatServer = (IChatServer)Activator.GetObject(typeof(IChatServer), uri);
}
public IChatServer ChatServer
{
get { return _ChatServer; }
}
}
}

Ambos os serviços consomem a classe RemotingTcpServicesHelper, responsável pelo registro do canal de comunicação TCP entre servidor e cliente. No caso, esta implementação foi definida de forma a alterar o nível de segurança da instanciação de objetos remotos para "Full" (o padrão do framework 1.1 em diante é "low", o que impossibilita a troca de objetos serializados).

Classe RemotingTcpServicesHelper
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Channels;
using System.Runtime.Serialization.Formatters;
using System.Collections;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting;
using net.jorgealbuquerque.Messager.Server;
namespace net.jorgealbuquerque.Messager.Core
{
public class RemotingTcpServicesHelper
{
public void ClientRegisterChannel(string serviceName, int port)
{
if (ChannelServices.GetChannel(serviceName) != null)
return;
IDictionary props = new Hashtable();
props["name"] = serviceName;
props["port"] = 0;
props["bindTo"] = "127.0.0.1";
props["typeFilterLevel"] = TypeFilterLevel.Full;
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientprovider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
TcpChannel channel = new TcpChannel(props, clientprovider, serverProvider);
ChannelServices.RegisterChannel(channel, false);
}
public void ServerRegisterChannel(string serviceName, int port)
{
if (ChannelServices.GetChannel(serviceName) != null)
return;
IDictionary props = new Hashtable();
props["name"] = serviceName;
props["port"] = port;
props["bindTo"] = "127.0.0.1";
props["typeFilterLevel"] = TypeFilterLevel.Full;
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
TcpChannel channel = new TcpChannel(props, null, serverProvider);
ChannelServices.RegisterChannel(channel, false);
}
}
}

Finalmente, encerra-se o desenvolvimento do assembly "MessagerCore", passando-se a construção da aplicação servidora pelo projeto console "MessagerServer":

MessagerServer
using System;
using System.Collections.Generic;
using net.jorgealbuquerque.Messager.Server;
namespace net.jorgealbuquerque.Messager.MessagerServer
{
class Program
{
static void Main(string[] args)
{
int port = 8080;
ServerChannelService service = new ServerChannelService(port);
Console.WriteLine("O servidor de mensagens está ativo na porta {0}", port);
Console.WriteLine("Pressine enter para parar o servidor...");
Console.ReadLine();
}
}
}

Observa-se a total abstração da lógica de negócios na camada de apresentação do servidor. Da mesma forma, apresenta-se o código fonte do único formulário (frmMain) para a aplicação cliente Windows Forms.

frmMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using net.jorgealbuquerque.Messager.Core;
using net.jorgealbuquerque.Messager.Client;
using System.Threading;
namespace net.jorgealbuquerque.Messager.MessagerClient
{
public partial class frmMain : Form
{
private Chatter _Chatter;
private IChatServer _ChatServer;
public frmMain()
{
InitializeComponent();
}
private void InitServer()
{
_Chatter = new Chatter(txtName.Text);
ClientChannelService service = new ClientChannelService(
txtServerHost.Text,
Int32.Parse(txtServerPort.Text));
_ChatServer = service.ChatServer;
_Chatter.IncomingMessage += new
Chatter.IncomingMessageEventHandler(Chatter_IncomingMessage);
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (_ChatServer != null)
_ChatServer.UnRegisterChatter(_Chatter);
}
catch
{
this.Dispose();
}
}
private void SendMessageToServer()
{
string texto = txtMessage.Text;
txtMessage.Text = string.Empty;
if (_ChatServer == null _Chatter == null string.IsNullOrEmpty(texto))
return;
_ChatServer.AddMessage(_Chatter, texto);
}
private void Chatter_IncomingMessage(string Message)
{
txtChat.Text = txtChat.Text + Message + "\r\n";
}
private void Send()
{
try
{
new Thread(new ThreadStart(this.SendMessageToServer)).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Register()
{
if (string.IsNullOrEmpty(txtName.Text))
{
MessageBox.Show("Nome inválido!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
InitServer();
_ChatServer.RegisterChatter(_Chatter);
pnlLogin.Visible = false;
pnlMain.Visible = true;
this.Text = string.Format("Usuário: {0}", txtName.Text);
}
catch (System.Net.Sockets.SocketException exSocket)
{
MessageBox.Show("Servidor não encontrado: " + exSocket.ErrorCode, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnSend_Click(object sender, EventArgs e)
{
Send();
}
private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(13))
Send();
}
private void btnRegister_Click(object sender, EventArgs e)
{
Register();
}
private void txtName_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(13))
Register();
}
}
}

O formulário foi divido em 2 panels (pnlLogin e pnlMain), responsáveis pelo login no servidor e pela interface principal do chat. Finalmente, apresenta-se o construtor da aplicação, onde é definido a flag CheckForIllegalCrossThreadCalls = false. Tal opção permite a chamada dos componentes do formulário por múltiplas threads.

Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace net.jorgealbuquerque.Messager.MessagerClient
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
frmMain.CheckForIllegalCrossThreadCalls = false;
Application.Run(new frmMain());
}
}
}