terça-feira, 14 de agosto de 2012

RES: [java-br] Socket

·

 

Ola Marcelo obrigado pelo interesse na ajuda.

Deixa eu te passar o cenário do problema:

Tenho um aplicativo rodando em Android que se comunica através de HTTP
(paginas jsp) com servidor Tomcat, trabalho com sistemas de rastreamento
cada aparelho me envia de 60 em 60 segundos sua id e localização.

Cada aparelho faz em media 5 requisições por minuto, incluso o envio de
localização, ae tu multiplica isso por 100 aparelhos e vamos chegar na casa
das 500 requisições por minuto, o que as paginas estão dando conta sem
problemas.

O meu problema está no consumo, pois cada requisição hoje, me enviando 0 ou
1 ou nada, consome no aparelho 1Kb, quando percebi que via socket consome
somente 1k, ou seja 1023k a menos.

Consegui depois de muito penar na web, construir um servidor socket assim
(sei que devo estar fazendo altos sacrilégios, mas foi como consegui chegar
e até então meu conhecimento em sockets era abaixo de zero) :

Na classe principal:

public static void main(String[] args) throws IOException {

ServerSocket serverSocket = new ServerSocket(PORTA);

System.out.println("INICIADO");

while(true){

Socket socket = serverSocket.accept();

new ServicoThread(socket).start();

}

}

Na classe Serviço:

public class ServicoThread extends Thread {

private final Socket socket;

public ServicoThread(Socket socket) {

this.socket = socket;

}

@Override public void run() {

try {

DataInputStream in = new
DataInputStream(socket.getInputStream());

DataOutputStream out = new
DataOutputStream(socket.getOutputStream());

ExecutaServico es = new ExecutaServico(in);

es.enviar(out);

out.close();

in.close();

socket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

Na classe executora assim:

public ExecutaServico(DataInputStream in) {

String nomeServico = "";

try {

this.servico = DataInputStream.readUTF(in).toString().trim();

if(servico.trim().equals("02")){

nomeServico = "LOCALIZACAO";

this.id = DataInputStream.readUTF(in);

this.latitude = DataInputStream.readUTF(in);

this.longitude = DataInputStream.readUTF(in);

this.velocidade = DataInputStream.readUTF(in);

}

public void enviar(DataOutputStream out) throws IOException{

if (this.servico.equals("02")) { //LOCALIZAÇÃO

int i = cadastrarPosicao();

if(i > 0){

out.writeUTF("1");

} else {

out.writeUTF("0");

}

}

public synchronized int cadastrarPosicao(){

int i = 0;

try {

cs = bd.conectar().prepareCall("{call
qry_001(?,?,?,?)}");

cs.setString(1, id);

cs.setString(2, latitude);

cs.setString(3, longitude);

cs.setString(4, velocidade);

i = cs.executeUpdate();

} catch (SQLException ex) {

ex.printStackTrace();

} finally {

try {

if (cs != null){

cs.close();

cs = null;

}

} catch (SQLException c){ }

bd.desconectar();

}

return i;

}

Bom via de regra geral funciona, mas não tenho coragem de colocar em
produção, porque não estou acreditando que este dará conta da quantidade de
requisições, com apenas dois aparelhos em laboratório, a quantidade de
deadlocks é pequena, mas existe, mas com um grande quantidade acredito que
vá explodir.

Se vc puder me ajudar a enquadrar isso que eu fiz até aqui, na maneira como
vc descreveu e conseguirmos montar alguma coisa que responda a uma grande
quantidade de requisições, a gente tenta encarar.

Fique a vontade se quiser me adicionar no MSN.

De antemão muito obrigado pelas informações, cara valeu.

Luciano

De: java-br@yahoogrupos.com.br [mailto:java-br@yahoogrupos.com.br] Em nome
de MarceloMF
Enviada em: terça-feira, 14 de agosto de 2012 11:01
Para: java-br@yahoogrupos.com.br
Assunto: Re: [java-br] Socket

Olá Luciano,

O protocolo http roda em cima do protocolo TCP, você provavelmente devera
escolher entre 2 protocolos:

TCP - Estabelece conexão, realiza o 3way handshake:
PC1 -------------->(SYN) PC2 (Primeiro pacote solicitando conexão)
PC2 ----->(SYN+ACK) PC1 (Segundo pacote confirmando o recebimento do
primeiro)
PC1 -------------->(ACK) PC2 (Terceiro pacote confirmando o recebimento do
segundo e estabelecendo a conexão)

UDP - Não estabelece conexão, não realiza o 3way handshake, por isso é
utilizado para funcionalidades como streeming.

Então é provável que você utilize o TCP, dessa forma você devera criar um
protocolo para trafegar suas informações, normalmente ele se divida em 2
partes:
header -> Informações gerais sobre o pacote/mensagem
payload -> Conteúdo do pacote/mensagem

Exemplo de header:
NOME_TRANSACAO(10POSICOES C/ " " A ESQUERDA)+TAMANHO_PAYLOAD(10POSICOES C/
0 A ESQUERDA)+PAYLOAD(VARIÁVEL)+HASH_PACOTE(64 POSIÇÕES)

Exemplo de payload:
NOME_INFORMACAO1(10POSIÇÕES C/ " " A
ESQUERDA)+TAMANHO_INFORMACAO1(10POSIÇÕES C/ 0 A
ESQUERDA)+INFORMACAO1(VARIÁVEL)
+NOME_INFORMACAO2(10POSIÇÕES C/ " " A
ESQUERDA)+TAMANHO_INFORMACAO2(10POSIÇÕES C/ 0 A
ESQUERDA)+INFORMACAO2(VARIÁVEL)
+NOME_INFORMACAO3(10POSIÇÕES C/ " " A
ESQUERDA)+TAMANHO_INFORMACAO3(10POSIÇÕES C/ 0 A
ESQUERDA)+INFORMACAO3(VARIÁVEL)

O seu pacote:
HEADER+PAYLOAD

Perceba que os campos do header são fixo e que o payload é variável. Como
você define o tamanho do payload e o tamanho de cada informação dentro do
payload, é possível realizar o parser da string tranquilamente.

Não sei qual sua necessidade, mas considere utilizar webservices, seja
rest, wsdl, ou mesmo JMS.

Depois de definido o layout do seu protocolo, virá a parte mais legal, que
é definir como o seu servidor irá processar essas mensagens.

Nesse ponto sugiro uma lida no livro Programação de rede Unix, Capitulo 30
-> Alternativas de projeto cliente/servidor, irei listar os tópicos, pois
sei que pode te ajudar.

30.4 - > Servidor TCP Interativo
30.5 -> Servidor TCP concorrente, um filho por cliente
30.6 -> Servidor TCP pré-bifurcado, sem bloqueio accept
30.7 -> Servidor TCP pré-bifurcado, bloqueio de arquivo em torno de accept
30.8 -> Servidor TCP pré-bifurcado, bloqueio de thread em torno de accept
30.9 -> Servidor TCP pré-bifurcado, passagem de descritor
30.10 -> Servidor TCP concorrente, um thread por cliente
30.11 -> Servidor TCP pré-threaded, um accept por thread
30.12 -> Servidor TCP pré-threaded, thread principal chama accept

Acima temos exemplos da utilização de forks e threads, no seu caso,
provável que utilize threads e definir como funcionara suas threads/pool de
threads será crucial para a escalabilidade da sua aplicação. Sugiro que
você abstraia a linguagem e se concentre nos conceitos... dessa forma você
irá conseguir desenvolver algo bacana.

O Java - Como programar do Deitel possui exemplos simples de como trabalhar
com sockets/threads, legal para fazer e ver funcionando, mas sinceramente
deixa a desejar e por isso recomendei o Programação de rede Unix como
literatura auxiliar.

Na mesma linha, você pode pesquisar sobre JAVA NIO(caso você possua *muitas
transações* concorrentes) e também se preocupar com a criptografia dos
pacotes... seja ela feita na camada de apresentação ssl/tls ou a nível de
aplicação, seja simétrica ou assimétrica.

Boa sorte! Inveja alheia... queria estar com um problema desses nas mãos
\o/.

[]s

--
Att, Marcelo M. Fleury
Blog - http://marcelomf.blogspot.com/
Slides - http://www.slideshare.net/marcelomf/

"O primeiro dever da inteligência é desconfiar dela mesma." By Einstein

[As partes desta mensagem que não continham texto foram removidas]

[As partes desta mensagem que não continham texto foram removidas]

__._,_.___
Atividade nos últimos dias:
Para sair da lista, envie email para: java-br-unsubscribe@yahoogroups.com
Para upload/download de arquivos: http://www.yahoogroups.com/files/java-br
Ofertas HP: ProBook 4430s

Quantidade ou qualidade? No Y!Encontros vc encontra de tudo um pouco.

Quantidade ou qualidade? No Y!Encontros vc encontra de tudo um pouco.
.

__,_._,___

0 comentários:

Pague com LPs do Mister Colibri

Pague com LPs do Mister Colibri
Quer comprar celular,Tablet,pen drive, GPS e muito outros produtos e ainda podendo pagar tudo em LPs ?Pois saiba que isso é possível,basta você visitar o site downloadstotal.com e realizar a sua compra com toda tranquilidade e segurança!!!

Hora

Online

Arquivo do Blog