O NeoMatrix Tech está de casa nova!

Você deverá ser redirecionado em 6 segundos. Se não, visite:
http://www.leonelfraga.com/neomatrixtech
e atualize seus favoritos.

Aviso IMPORTANTÍSSIMO!

Aviso aos navegantes:

O NeoMatrix Tech mudou de casa!!!

A partir de agora, acessem pelo novo endereço:

http://www.leonelfraga.com/neomatrixtech

Ué... mas é só o domínio mudou de lugar?

R: Na verdade, não é bem assim hehe. Este domínio que você acessa agora aponta para um blog hospedado no Blogger, enquanto no novo, aponta para um blog na plataforma Wordpress, hospedagem própria, muito mais rápida e com um layout mais agradável de ler ;)

Não vou fechar este domínio igual ao que eu fiz com o NM Light (que já está 100% na nova plataforma). Talvez beeeeeeem depois eu faça isso.

Todos os posts daqui se encontram lá, e novos posts serão colocados somente no novo endereço.
A única coisa que não consegui importar foram os comentários. Mas em breve vai ter um post contando sobre a epopéia que foi migrar o NeoMatrix Tech!

Somente vou fechar a área de comentários daqui. Caso queiram comentar, favor ver o post correspondente no "Novo NeoMatrix Tech" e comentem por lá. É bem melhor! (pena que os permalinks "amigáveis para SEO" não funcionam lá, dá erro 404 e não consigo fazer a configuração funcionar. E olha que eu já vi vários artigos falando desse assunto :( ).

Quem assina o feed, já está lendo o conteúdo do novo NeoMatrix Tech!

terça-feira, 27 de maio de 2008

Exemplo de uso do Framework SQL

Olá pessoal! Agora sim, sai o exemplo de utilização do framework SQL que apresentei nos primeiros artigos deste blog!

O programa consiste em demonstrar as operações básicas (select, insert e update) da classe Conexao através de um mini-cadastro de clientes.
São poucos campos, mas não importa, é o mesmo procedimento para tabelas maiores ;-)

A aplicação está preparada para rodar em banco de dados Firebird e SQL Server, o que vai definir qual BD a aplicação irá rodar depende de apenas uma configuração no arquivo web.config.

No arquivo, disponibilizo:

- Aplicativo Web (as telas não estão formatadas, já que o principal intuito do programa é a demonstração da classe de Conexao).
- Bibiliteca de Classes, que é o núcleo da aplicação. A camada que trata as regras e a conexão com o banco de dados. Além da classe Conexao (o nosso Framework SQL), temos um arquivo Consts.Funcoes.cs, que contém funções que costumo utilizar sempre, principalmente para conversão de objetos nulos em valores padrão.
- Arquivo Firebird 2.0 (.fdb) com o banco de dados.
- Arquivo SQL Server 2005 (.mdf e .ldf) - usei o SQL Server 2005 Express para a criação.
O projeto foi feito no Visual Studio 2005 e você precisará dos seguintes componentes instalados:
- Extensões AJAX (ASP.NET Ajax)
- Firebird Client 2.0.1 (pode ser mais recente, porém a referência precisará ser refeita)

O arquivo está disponível na seção de downloads do blog: Página de Suporte do NeoMatrix Tech no final do post.


Para acompanhar o artigo, sugiro que façam o download do mesmo, pois "resumi" bastante o código aqui.
Antes, um pequeno adendo referente as alterações que precisei fazer na classe Conexao:
Quando compilamos um projeto com suporte a mais de um mecanismo de banco de dados, o VS informa um erro de variável declarada múltiplas vezes.
O erro ocorria quando nas propriedades do projeto da biblioteca de classes habilitávamos mais de um mecanismo de BD a variável TipoBD era declarada múltiplas vezes, acompanhem:

   1: public class Conexao
   2: {
   3:     ...
   4:     #if FIREBIRD
   5:     public static TTipoBancoDados TipoBD = TTipoBancoDados.tbFireBird;
   6:     #endif
   7:     #if SQLSERVER
   8:     public static TTipoBancoDados TipoBD = TTipoBancoDados.tbSQLServer;
   9:     #endif
  10:     ...
  11: }


Com as duas diretivas informadas, o código de declaração da variável TipoBD se repetia, coisa que não acontece quando usamos suporte a apenas um mecanismo de banco de dados.

Solução:

Se vocês notaram, a classe Conexao não possui um construtor declarado. A primeira coisa que eu fiz foi declarar este construtor, de maneira que quando instanciamos Conexao a partir de uma classe derivada, o código fosse executado.

Com isso, declarei a variável TipoBD fora do construtor (continua sendo uma variável estática, de classe) e a atribuição do tipo de BD referente a diretiva de compilação foi colocada dentro do construtor. Mas aí ainda tinha um problema: Quando executado com suporte a mais de um BD, era sempre a última atribuição que ficava. Fiz um código que pega, a partir de uma chave no arquivo de configuração da aplicação, determinasse qual banco de dados a aplicação irá utilizar.
O código final ficou:

   1: public class Conexao
   2: {
   3:     protected static TTipoBancoDados TipoBD;
   4:     public Conexao()
   5:     {
   6:     #if FIREBIRD
   7:     /// <sumarry>
   8:     /// Indica o banco de dados a ser utilizado na aplicação. Basta definir aqui e todos os objetos herdeiros irão utilizar este banco.
   9:     /// </sumarry>
  10:     TipoBD = TTipoBancoDados.tbFireBird;
  11:     #endif
  12:     #if ORACLE
  13:     /// <sumarry>
  14:     /// Indica o banco de dados a ser utilizado na aplicação. Basta definir aqui e todos os objetos herdeiros irão utilizar este banco.
  15:     /// </sumarry>
  16:     TipoBD = TTipoBancoDados.tbOracle;
  17:     #endif
  18:     #if SQLSERVER
  19:     /// <sumarry>
  20:     /// Indica o banco de dados a ser utilizado na aplicação. Basta definir aqui e todos os objetos herdeiros irão utilizar este banco.
  21:     /// </sumarry>
  22:     TipoBD = TTipoBancoDados.tbSQLServer;
  23:     #endif
  24:     #if ODBC
  25:     /// <sumarry>
  26:     /// Indica o banco de dados a ser utilizado na aplicação. Basta definir aqui e todos os objetos herdeiros irão utilizar este banco.
  27:     /// </sumarry>
  28:     TipoBD = TTipoBancoDados.tbODBC;
  29:     #endif
  30:     #if OLEDB
  31:     /// <sumarry>
  32:     /// Indica o banco de dados a ser utilizado na aplicação. Basta definir aqui e todos os objetos herdeiros irão utilizar este banco.
  33:     /// </sumarry>
  34:     TipoBD = TTipoBancoDados.tbOleDb;
  35:     #endif
  36:     if (ConfigurationManager.AppSettings["BD"] != null)
  37:     {
  38:     string bd = ConfigurationManager.AppSettings["BD"] != null ? ConfigurationManager.AppSettings["BD"].ToString().ToUpper() : "FB";
  39:     switch (bd)
  40:     {
  41:     case "FIREBIRD": { TipoBD = TTipoBancoDados.tbFireBird; break; }
  42:     case "SQLSERVER": { TipoBD = TTipoBancoDados.tbSQLServer; break; }
  43:     case "ORACLE": { TipoBD = TTipoBancoDados.tbOracle; break; }
  44:     case "OLEDB": { TipoBD = TTipoBancoDados.tbOleDb; break; }
  45:     case "ODBC": { TipoBD = TTipoBancoDados.tbODBC; break; }
  46:     default: goto case "FIREBIRD";
  47:     }
  48:     }
  49:     ...
  50: }


Com isso, caso a aplicação necessite rodar em mais de um mecanismo de banco de dados, deverá existir no seu arquivo de configuração uma chave chamada "BD", e o valor é a diretiva de compilação correspondente ao banco de dados que se queira utilizar.

Caso necessite de apenas um mecanismo, o mesmo é determinado pela própria diretiva de compilação, como era feito antes, sem a necessidade do atributo BD no arquivo de configuração.

O arquivo corrigido está disponível para download na área de suporte do blog (link acima)

Agora, vamos a uma breve descrição do exemplo:

Primeiramente, temos uma bibiloteca de classes que é a responsável pela busca e gravação dos registros no Banco de Dados. Em seguida, uma interface web que faz referência a esta biblioteca de classes.

Criei uma classe chamada TCliente, cujas propriedades são os campos da tabela, e possui métodos de pesquisa, setar as propriedades através de um ID, exclusão, inclusão e alteração.
O método de inclusão, demonstra também como utilizar stored procedures do BD através das propriedades e métodos da classe Conexao e a captura dos valores de retorno.

Os métodos também exploram o conceito de instruções SQL parametrizadas, com declaração de parâmetros, montagem de filtros e execução.

Veja como ficou simples o código.

Do lado da aplicação web, na primeira página, temos campos de filtro e dois botões. Um deles executa a pesquisa e retorna os resultados para um GridView. Outro encaminha para uma página de manutenção de registros. Nestas páginas, não temos nenhuma referência à web.config, providers de bancos de dados e tal, somente chamadas à classe TCliente.

Entendendo o código:

Em TCliente, primeiramente declarei as variáveis privadas, é com elas que iremos manipular os dados dentro da classe. Elas estão expostas através de propriedades, para que outras classes possam atribuir e receber valores. Temos dois construtores, um construtor básico, sem parâmetros, que simplesmente executa o construtor da superclasse; e outro construtor em que passamos um ID para carga de dados.

- Método SetByID:
Este método recebe um código de cliente e tras os seus dados para as propriedades de uma instância de TCliente. Ele faz o uso do método Select() da classe Conexao: É definido no atributo _Select a instrução SQL responsável por trazer os dados de um único registro da tabela Clientes. Ele é definido como uma query parametrizada da seguinte forma:

   1: _SelectSQL = "select * from CLIENTES where CODIGO_CLIENTE = @PCLIENTE";


Com esta instrução, limpamos a lista de parâmetros SQL de Conexao e alimentamos com o parâmetro "@PCLIENTE" e chamamos a instrução _Select(true). Se executada com sucesso, todos os campos da tabela serão retornados na coleção ListaCamposTabela, e podemos atribuir os valores dos itens dela para as propriedades de TCliente. Como cada campo é indexado pelo nome em uma propriedade this[] indexada, usei a seguinte atribuição:

   1: _CPF = Consts.Funcoes.NullOrString(this["CPF"]);


A função Consts.Funcoes.NullOrString garante que caso o campo venha nulo, seja atribuido para a propriedade uma string vazia, evitando o erro de tentativa de atribuição de null.

- Método Inserir()
Este método consiste em executar uma stored procedure utilizada para inserção do registro no banco de dados. O campo CODIGO_CLIENTE é auto-incrementado, ou seja, o usuário não tem controle deste valor. No Firebird, implementei-o através de um generator e no SQL Server, declarei-o como identity. A procedure pega o código a ser inserido, insere os valores no BD e volta no parâmetro de saída o código inserido.
Os parâmetros são declarados da forma usual, com AddSQLParam, e o resultado da procedure é obtido via coleção de objetos TCampoCadastro. Portanto, retornamos o resultado da SP em uma coleção deste tipo:

   1: List<TCampoCadastro> procresults = executeStoredProcedure("SP_INSERIR_CLIENTE", true);


Muito importante saber a ordem de declaração dos parâmetros, já que para recuperá-los da coleção temos que saber seu índice.

- Método Atualizar()
Este método consiste em atualizar, através de uma instrução UPDATE, um registro do BD.
A instrução UPDATE é definida em _UpdateSQL, parametrizada, e os parâmetros declarados. Em seguida, é chamada uma sobrecarga do método Salvar() em que é indicada a operação de atualização e confirmada a instrução SQL parametrizada.

- Método Excluir()
Análogo ao método Atualizar(), porém o SQL é informado em _DeleteSQL e passado a opção de exclusão em Salvar().

- Método Pesquisar()
Retorna um dataview com o resultado da pesquisa com os filtros especificados nos parâmetros da função.
Escolhendo o BD a ser utilizado:

Abrindo o arquivo web.config, na seção AppSettings, temos o atributo obrigatório strConexao declarado. É nele em que você vai colocar a string de conexão referente ao banco de dados utilizado na aplicação. Há exemplos para Firebird e SQL Server usando Windows Authentication. Lembre-se que somente um deles poderá ser usado por vez.
Como estamos compilando o suporte a dois mecanismos de BD ao mesmo tempo, fez-se necessário a criação de um atributo BD para controlar qual o BD a ser utilizado. E note que tanto em um BD como em outro, o código é o mesmo, só mudando o arquivo de configuração.


Pronto, com este exemplo, você será capaz de executar as operações básicas da Classe de Conexão!!! :-)

Exemplo de uso do Framework de Conexão (354 KiB)

Leia o restante deste post...

quarta-feira, 14 de maio de 2008

Streaming no N95 via WiFi utilizando o RealPlayer

Olá Pessoal! Quebrando um pouquinho as dicas de programação, hoje posto um tutorial que promete resolver o problema de muita gente que possui este maravilhoso smartphone da Nokia, realmente, faz juz ao nome "N", pois faz "N" coisas mesmo.

Página do YouTube Mobile no N95 A situação é a seguinte: Você feliz da vida, com seu celular conectado à uma rede WiFi, entra no YouTube Mobile (por exemplo) pelo navegador nativo do aparelho. Pesquisa um vídeo legal no site, entra nele e clica no link "Watch Video" e o RealPlayer embutido no celular dá as caras. Eis que a conexão é feita e no celular aparece um popup com os dizeres "Carregando" e não enche nem um "tiquinho" da barra de progresso e em alguns segundos surge a mensagem "Impossível conectar ao servidor. Tempo limite da conexão esgotado" e com certeza começa a chingar: "P*, pela conexão da minha operadora funciona legal! E no WiFi a Internet (sites da web) vai de boa :-(".

Com qualquer link de streaming (pelo protocolo rtsp que o Real Player do N95 suporta) acontece a mesma coisa: Pela rede da operadora celular vai de boa, mas via WiFi não. E claro, sabemos bem que para quem não tem um plano ilimitado de dados, alguns videozinhos no YouTube Mobile ou qualquer streaming bem longo já são suficientes para estourar a conta (e esvaziar o nosso bolso). E com o WiFi não acontece isso, já que você vai ter o conforto de aproveitar a conexão banda-larga que está plugada na sua rede.
Pesquisei pelo Google, e entrei em diversos fóruns (brasileiros e gringos por sinal), alguns resultados me levaram nos fóruns da Nokia, mandaram configurar os parâmetros do Streaming no N95, proxies e tal, mas nada de funcionar.

Eis que nuns dos "insights" da vida, me surge um pensamento: Qual é a diferença entre celular estar conectado à uma rede de pacotes (rede da operadora) ou a uma rede WLAN (WiFi)? R: Pela rede de pacotes, o celular está conectado DIRETAMENTE à Internet, ou seja, possui um endereço IP válido na rede e as portas não passam em um router/firewall, o que não acontece quando ele está conectado via WLAN, ou seja, ele está plugado em um router e não diretamente na Internet, possuindo um endereço IP local.

Como vocês devem saber, para alguns programas de compartilhamento (vide eMule, SoulSeek, entre outros) para funcionar em uma LAN é necessário redirecionar as portas (tanto TCP como UDP) que o programa utiliza para a máquina em que o programa em questão está rodando.

Daí fiz essa analogia com o funcionamento do RealPlayer do N95: Alguma coisa deve estar bloqueando as portas necessárias para o streaming ser realizado, já que algumas informações são obtidas via HTTP mesmo, porém o fluxo de dados é via protocolo rtsp e as portas devem estar bloqueadas no router.

Para este tutorial, irei utilizar o smartphone N95-1 (RM-159), com a versão 21.0.0.16 do Firmware e um roteador DLink DI-624 AirPlus Xtreme G. Mas o conceito é válido para qualquer roteador.


Configurando o seu Roteador:

A chave da solução consiste em colocar a interface WLAN do N95 na zona desmilitarizada (DMZ) da rede, ou seja, expor a interface WLAN do celular diretamente na Internet sem a proteção de um firewall e tradução NAT, com todas as portas passando por ele.

Mas tem um porém: Para colocar uma interface de rede na DMZ, precisamos saber o endereço IP da mesma, e quando conectamos o N95, o mesmo ganha um IP via servidor DHCP do roteador, e este pode designar um IP diferente a cada conexão.

Primeiro, vamos mandar o servidor DHCP do roteador designar o MESMO IP em todas as conexões. Isto é feito utilizando o MAC Address da iinterface WLAN do N95.

Siga os passos:

- Anote o MAC Address da interface WLAN do celular. Ele pode ser encontrado na etiqueta no compartimento da bateria, acima do slot do SIM Card, com os dizeres WLAN: seguida do MAC.
Localização do MAC Address no N95

- Com um browser, entre na interface administrativa do router, e nela, vá até a aba Home e clique na opção DHCP, a última no lado esquerdo da tela.

- Certifique-se de que o servidor DHCP esteja habilitado e veja a faixa de IP que ele irá atribuir aos dispositivos da rede, por exemplo, de 100 até 199 (minha rede, por exemplo, é do tipo 192.168.0.x).

- Na seção Static DHCP, em Name coloque um nome sugestivo, tipo "Meu N95", em IP coloque um número que se encontra na faixa de IP que o DHCP pode servir, por exemplo, 100. Então, toda vez que o celular se conectar na rede, ele ficará com o IP 192.168.0.100.

- Em MAC Address, coloque o MAC Address da interface WLAN do seu N95.

- Marque a opção "Enabled".

- Clique no botão Apply e espere o roteador ser reiniciado.

Configurando o DHCP Estático  

Pronto, o que fizemos acima foi atribuir um IP fixo para o celular, ou seja, a cada vez que ele se conecta na rede, receberá o mesmo IP.

Agora, no roteador, clique na aba "Advanced" e em seguida na opção DMZ, no lado esquerdo. Selecione a opção Enabled, e em IP Address, coloque o IP atribuído para o celular (no meu caso, 192.168.0.100). Clique em Apply.

Certifique-se de que o firewall está liberando as portas da WAN para a LAN.

Com isso, a configuração no roteador está concluída.

Configurando a DMZ  

Configurando seu N95:


Primeiro, configure o ponto de acesso correspondente à sua conexão WiFi no celular: Na tela de espera, clique sobre o aplicativo de pesquisa automática de WLAN. Caso ele encontre mais de uma rede, selecione a opção Procurar WLAN para mostrar a lista de rede. Achou seu ponto de acesso na lista? Então clique sobre ele, informe a chave criptográfica se necessário, e entre em um site da Web. Com isso, o ponto de acesso está configurado.

 Selecionando a WLAN no N95
Agora, precisamos configurar o RealPlayer para que quando for solicitado a abertura de um link streaming, ele utilize a conexão WiFi ao invés do pacote de dados da sua operadora:
Pressione o botão Menu, selecione Ferramentas -> Config -> Aplicativos -> RealPlayer -> Streaming. Selecione a opção Rede e clique na opção "Ponto de Acesso Padrão" e selecione o ponto de acesso da sua rede WiFi. Deixe Tempo Online na opção "Sem Limite", e os valores utilizados nas opções Porta UDP mais baixa e Porta UDP mais alta configure em 1024 e 65535, respecitivamente. As configurações avançadas (acessíveis clicando em Opções -> Configs. Avançadas na tela de configurações do RealPlayer) podem ser deixadas na padrão. Feitas as configurações, acione o botão Voltar para ir à tela anterior.

Na opção Proxy, em Usar Proxy deixei a opção como "SIM", Endereço do Proxy como vazio (Nenhum) e a porta em 1091.

Configurações do Real Player no N95

Com isso, configuramos o RealPlayer do N95 com a conexão WiFi.

Agora, entre no YouTube Mobile, ache um video legal, clique no Watch e seja feliz (claro, se o o pessoal do YouTube codificou direitinho o vídeo para 3GP) :-)

Vídeo rodando no N95  
Também fiz o teste com uma rádio online que transmite sobre o protocolo rtsp e funcionou: rtsp://streaming.rte.ie/redundant/1516.rm

Abraços a todos!!!

Leia o restante deste post...

Sobre o NeoMatrix Tech

Meu blog para assuntos profissionais, ligado com tecnologia.
Dicas de programação (grande parte de C# e ASP.NET, mas não limitado a essa plataforma :-) ), dicas de utilitários, análises de equipamentos e serviços, resenhas sobre sites que eu visito, relacionados com tecnologia, opinião sobre mercado de trabalho, metodologias de desenvolvimento, comportamento no mundo tecnológico...

NeoMatrix Light

  © Blogger templates ProBlogger Template by Ourblogtemplates.com 2008 - Editado e configurado por Leonel F.

Voltar ao TOPO