quinta-feira, 25 de agosto de 2011

O legado de Steve Jobs

Steve Jobs se afasta da Aplle então segue uma pequena homenagem com um pouco de historia. Steve Jobs sem dúvida foi um dos maiores gênios da computação. Abaixo uma foto dele ao lado do computador Lisa lançado em 1983.


O interessante desse computador é que foi um dos primeiros á possuírem interface gráfica e mouse, e foi um modelo seguido ate dos dias hoje pelos computadores que usamos, porem esse computador não foi o grande sucesso da Apple muito menos de Jobs, muito pelo contrario esse computador foi um fracasso de vendas, eu acredito que por uma razão bem simples, as idéias de Jobs estavam a frente do hardware e do software, seu projeto contava com um processador Motorola de 5 MHz seu sistema operacional operava em multitarefa e gerava gráficos tudo muito inovador alem do mouse já citado. Para suportar toda essa inovação o Lisa continha 1 MB de memória RAM o que era um absurdo para época em que os computadores esnobavam com 96 KB, isso evidentemente elevou bastante o preço, e poucos apostaram na inovação, o que tornou o Lisa um fracasso comercial. A Apple acabou por suspender as vedas criou o projeto Macintosh o Lisa virou Lisa 2 e depois Macintosh XL. Se você tiver oportunidade de ver um Aplle Lisa tenha certeza que está diante de uma inovação maravilhosa da tecnologia que utilizamos hoje. Abraços e melhoras para Jobs =)

domingo, 3 de julho de 2011

Chat no Delphi

Olá prezados leitores,
Hoje vamos implementar um chat ou programa de bate papo. Devido ao enorme sucesso do artigo passado: (http://www.activedelphi.com.br/modules.php?op=modload&name=News&file=article&sid=249&mode=mode=thread&order=0&thold=0) resolvi lançar uma versão atual, com uma utilização prática. Escolhi um chat, pois percebi que a grande maioria dos leitores foram atrás do site buscando uma solução para fazer seus próprios MSNs da vida.
Bem, a teoria sobre Cliente e Servidor você pode ver no artigo citado acima, combinado? O único pro é que tem que ser cadastrado no site para visualizar o artigo. Quero apenar evitar que esse artigo se torne longo demais e cansativo...
Ligando os artigos
Muita coisa mudou... antes era Delphi 7 agora é XE antes eram componentes TServerSocket e TCLientSocket, mudaram os componentes mudaram os eventos, agora vamos utilizar TidTCPServer e TidTCPClient. Isso mesmo os componentes INDY.
A idéia base é a mesma os conceitos são os mesmo, o que vai mudar são os eventos que vamos utilizar, ficou um pouco mais complicado porem com mais funcionalidades, talvez você precise ler duas ou três vezes alguns trechos, é normal, principalmente se é primeira vez que estiver usando esses componentes.
O TidCPServer alem de ser um componente mais robusto tem um evento OnExecute que vai “informar” qual cliente fez algo. Já o TidTCPClient não nos da muitas pistas nem dispara evento quando algo chega. Então vamos criar um Thread simples para ficar lendo e vamos usar uma outra classe para processar as mensagens recebidas. Vamos agora dar uma pequena revisada para facilitar nossa compreensão e tirar algumas dúvidas:
Como foi explicado no artigo passado, mas é bom da um reforço aqui:
1) Todo chat é pelo menos um cliente e um servidor
2) Todo cliente se liga em um servidor de cada vez
3) Para cada TCPClient me conecto em um Servidor(TidTCPServer)
4) Um Servidor por sua vez pode ter vários clientes conectados.
5) Para um cliente enviar informações para outro cliente a menssagem vai necessariamente passar pelo servidor.
Acho que essas nossas principais “Leis” então, entendido isso vamos em frente....

PRIMEIRO O SERVIDOR
Vamos primeiro ao servidor pois requer um pouco mais de cuidado e atenção. Seu layout de tela é muito simples ele não vai ter interação com o usuário praticamente, salvo um botão para ligar e desligar o cliente. E um memo que vai exibir todo o trafego no servidor. Nossa tela então ficou assim:
Observe que vou mudar o nome de alguns componentes bem como do Form. Observe também que foi incluído o Componente TidTCPServer.

Codificando o servidor
Vamos criar uma pequena estrutura para guardar algumas informações dos nossos clientes, como IP, Host, HoraConexao, e a Conexão dele. Segue abaixo minha estrutura, pode ser uma classe também, vai mudar um pouco as coisas, mas pode ser feito. Mas a minha ficou assim:
Type
TCliente = Record
IP : string[15];
HostName : string[40];
ThreadID: Cardinal;
Connection: TidTCPConnection;
end;
PCLiente = ^TCliente;
Atenção: Vc deve declarar no USES IdTCPConnection para a classe TidTCPConnection possa ser entendida pelo compilador.

Minha idéia é guardar algumas informações do cliente quanto conectar no caso ai está apenas o IP através do IP iremos pegar o Host, vamos ver mais a frente o ID do Thread não precisamos saber muito disso agora, e o mais importante é o Connection que é por onde vamos nos comunicar com os clientes.
Agora vamos criar uma Lista de conexões isso é familiar para você, se tiver lido o artigo SOCKETS que foi citado no inicio deste artigo. =) Veja como ficou:



A única configuração que temos que fazer no idTCPServer é sua propriedade DefaultPort, que como o nome já disse é a porta padrão, lembra do socket? IP e porta? É isso ai... escolha uma porta que mais lhe agrada no meu caso usei a 1212.


Meu numero da sorte =) Escolha um numero qualquer para sua porta o importante é que a mesma porta do servidor seja a mesma do cliente e que não esteja sendo usando por outra aplicação.
CODIFICANDO OS EVENTOS
Form
OnCreate
procedure TFServidor.FormCreate(Sender: TObject);begin FConexoes := TList.Create;end;
OnDestroy
procedure TFServidor.FormDestroy(Sender: TObject);begin DesconectarTodos; FConexoes.Free;end;
Botões
Ativar: onClick
procedure TFServidor.Button1Click(Sender: TObject);begin IdTCPServer1.Active := True;end;
Desativar: onClick
procedure TFServidor.Button2Click(Sender: TObject);begin if IdTCPServer1.Active then IdTCPServer1.Active := False;end;
TidTCPServer
OnConnect
procedure TFServidor.IdTCPServer1Connect(AContext: TIdContext);var ClienteNovo : PCLiente;begin GetMem(ClienteNovo,Sizeof(TCliente)); ClienteNovo.IP := AContext.Connection.Socket.Binding.PeerIP; ClienteNovo.HostName := GStack.HostByAddress(ClienteNovo.IP); ClienteNovo.Connection := AContext.Connection; AContext.Data := TObject(ClienteNovo); FConexoes.Add(ClienteNovo); // Adicionando na listaend;
Aqui para utilizar o GStack é preciso adicionar no uses IdStack.
OnDisconnect
procedure TFServidor.IdTCPServer1Disconnect(AContext: TIdContext);Var Cliente : PCliente;begin Cliente := PCliente(AContext.Data); FConexoes.Remove(Cliente); AContext.Data := nil; FreeMem(Cliente,SizeOf(TCliente));end;
OnExecute
procedure TFServidor.IdTCPServer1Execute(AContext: TIdContext);var Cliente : PCliente; Msg: string; i :integer;begin Cliente := PCliente(AContext.Data); Msg := '<' + Cliente.IP + '>:'; Msg := Msg + Cliente.Connection.IOHandler.ReadLn; memolog.Lines.Add(Msg); BroadcastMsg(Msg);end;
A idéia aqui é redirecionar o que chegou para todos os outros clientes conectados, ou seja que estão na nossa lista FConexoes; Observer que tem no final uma procedure chamda de Broadcast(); Ela vai fazer o trabalho de percorrer nossa lista e enviar a variável Msg para todos os clientes. Segue o código:
procedure TFServidor.BroadcastMsg(_msg: string);var i : integer; Cliente : PCLiente;begin for I := 0 to FConexoes.Count-1 do begin Cliente := PCliente(FConexoes.Items[i]); Cliente.Connection.IOHandler.WriteLn(_msg); end;end;
Servidor está pronto =) Escolha a porta a seu gosto é importante rodar talvez o windows peça para você desbloquear sempre que mudar de porta, certifique-se que a porta escolhida não está sendo utilizada por outro programa.
Codificando o Cliente
Bem a interface de todo chat é praticamente a mesma, segue a nossa:


É um TMemo em cima um TEdit em baixo e um botão enviar, deixei os nomes padrões para você identificar facilmente cada um. O importante ai é ver que circulei na imagem para destacar que já deixei configurado a dupla IP e Porta =) Para quem não sabe o IP 127.0.0.1 é o ip da nossa própria maquina independente do ip real dele, pode ate ser que nem ip tenha, o ip 127.0.0.1 foi criado para testes mesmo é o mesmo que localhost.
Agora vamos codificar nosso cliente... ta perto do fim já =) Devemos iniciar declarando essas duas clases
type
TOnReceiverThread = class (TThread)protected FConexao : TIdTCPConnection; procedure Execute; override;
public constructor Create(_Conexao: TIdTCPConnection); reintroduce;
end;
TOnProcessa = class(TIdSync)protected FMsg: string; procedure DoSynchronize; override;
public constructor Create(const _Msg:string); class procedure AddMsg(const _Msg:string);
end;
Não se esqueça do IdTCPConnection no USES;
A primeira classe é um Thread se você não sabe o que um Thread recomendo que leia algo sobre isso urgente. Mas entenda que é como disparar um processo paralelo em nossa aplicação. Então ele vai ficar executando o comando IOHandler.ReadLn durante todo tempo O FConexao é nosso componente IdTCPClient;
A segunda classe é que vai processar, estou usando um artifício bastente interessante dentro da minha classe crio uma class procedure e dentro dela disparo a criação da classe e na criação da classe preencho a variável FMsg, já e na procedure DoSynchronize faço a ação de pegar o que está no FMsg e adcionar o memo. Segue o código:
{ TOnReceiverThread }
constructor TOnReceiverThread.Create(_Conexao: TIdTCPConnection);begin FConexao := _Conexao; inherited Create(False);end;
procedure TOnReceiverThread.Execute;begin while not Terminated and FConexao.Connected do begin TOnProcessa.AddMsg(FConexao.IOHandler.ReadLn); end; inherited;end;
{ TOnProcessa }
class procedure TOnProcessa.AddMsg(const _Msg: string);begin with Create(_Msg) do try Synchronize; finally Free; end;end;
constructor TOnProcessa.Create(const _Msg: string);begin FMsg := _Msg; inherited Create;end;
procedure TOnProcessa.DoSynchronize;begin inherited; Form2.Memo1.Lines.Add(FMsg);end;
Declare uma variável com seu thread o meu ficou assim
var FCliente: TFCliente; Receiver : TOnReceiverThread; // Aqui meu thread
Acredito que essa seja a parte mais complicada, por isso analise com calma se for preciso releia e observe as ligações meu thread que chamei de RECEIVER vai ser criando no evento OnConnected que veremos a seguir, depois ele vai agir sozinho e dentro no Execute ele chama a class procedure do TOnProcessa;
Agora os eventos....Primeiro o botão enviar:
procedure TFCliente.BitBtn1Click(Sender: TObject);begin IdTCPClient1.IOHandler.WriteLn(edit1.Text);end;

Ao clicar envia para o servidor o que estiver no Edit.
onCreate do Form
procedure TFCliente.FormCreate(Sender: TObject);begin IdTCPClient1.Connect;end;
onConnected e OnDisconnected
procedure TFCliente.IdTCPClient1Connected(Sender: TObject);begin Receiver := TOnReceiverThread.Create(IdTCPClient1);end;
procedure TFCliente.IdTCPClient1Disconnected(Sender: TObject);begin if Receiver <> nil then begin Receiver.Terminate; Receiver.WaitFor; FreeAndNil(Receiver); end;end;
Naturamente o cliente deve ser iniciado após o servidor estar ativo. Caso contrario ele vai de caro da um erro e informar um numero (um código de erro) esse código é padrão para toda aplicação com sockets por exemplo 10061 = Não foi possível conectar. Provavelmente servidor não está rodando, se tiver pode ser a porta diferente da sua ou ainda, está rodando mas não está ativo. Esses são os 3 problemas mais comuns. O outro é colocar um IP não valido para cliente se conectar, para testar se o ip é valido para conectar é o so dar o vamos comando PING no prompt se houver resposta positiva, verifique as portas.
Na internet você acha fácil um lista com esses erros. Em uma busca muito rápida encontrei esse link: http://claheadshot.forumeiro.com/t626-lista-de-erros-de-socket-e-suas-causas
Se o link estiver quebrado não desespere é realmente muito fácil encontrar basta buscar “lista de erros sockets” há muito mais material.
CONSIDERAÇÕES FINAIS
Há muita coisa para implementar, =) Nick name, logs, enviar arquivos, trocar o memo por um report mais interativo que suporte imagem e formatação de textos como negrito, quem souber de um bom componente me avise. Já no lado servidor, podemos colocar regras para banir ips, ir salvando o log em arquivo txt, alem de implementar um protocolo que permita mensagens privadas e muitas outras coisas... Mande sua idéia, vou criar outros artigos apartir deste no futuro, aqui foi o ponta pé inicial =) Acredito que tudo ficou claro na codificação, se necessário envio os fontes. Basta mandar um e-mail para jnelson3@ig.com solicitando.
Deste já agradeço por ter lido, espero que tenha gostado um abraço e ate o próximo

quarta-feira, 22 de junho de 2011

Historinha - Ted Hoff Jr.

Existem inovações que tem a capacidade de dar uma nova direção pra humanidade. Marcian Hoff pra mim foi uma dessas pessoas que aparecem com uma idéia aparentemente ingênua , a idéia dele foi nada mais nada menos que “vamos fazer um chip que atenda a comandos” Sim ele inventou o processador! Reza a lenda que ele foi o décimo segundo funcionário da Intel. E que, uma certa empresa japonesa apareceu na Intel para construir um chip de uma calculadora que eles estavam projetando. Foi então que Marcian Edward Hoff Jr, o grande “Ted” apareceu com a brilhante idéia de desenvolver não um circuito convencional e sim um que executasse comandos predefinidos. Isso foi em 1968 já em 1971 a Intel já comercializava o primeiro processador chamado de 4004 de 4 bits. Mas as lições que tiro aqui são: preparo, esse cara era PhD, ter a sensibilidade para notar as boas idéias, investir em idéias inovadoras. Busquem, há muita informação sobre ele. Mas claro, como sempre...a maioria das boas informações estão em inglês. =)

segunda-feira, 20 de junho de 2011

Recomeço - Dica de site

Prezados leitores,

Voltei =) Esse “post” marca uma retomada, e espero não parar mais. Finalmente estou formado é um grande sonho realizado.
Como a idéia aqui é não deixar ninguém na mãe, muito ficaram na dúvida, onde conseguir os programas utilizados e principalmente PROTEUS e CCS. Quero deixar aqui um link de um blog que não somente esses softwares como muito outros e muito material de áreas afim. Realmente recomendo tenho certeza que se você não conhece vai gostar de conhecer. Segue o link:








Há muito material interessante, sobre PIC, CCS, Mikro C, Proteus, apostilas de eletrônica, mecatrônica, livros aproveitem muito bom o blog dele. Sem mais ficou ai a dica. Abraços e bons estudos.