Bom dia pessoal !!
Estou aqui mais uma vez para pedir o auxílio de vocês(Quem sabe um dia se eu ficar bom em Java o quanto eu sou em .Net eu começe a ajudar também) para uma coisa que é mais uma dúvida do que um problema.
Estou fazendo um aplicativo Cliente-Servidor usando Java no Servidor e é óbvio o Cliente é J2ME. Já escrevi muitas aplicações Cliente-Servidor em .Net, e me deparei com uma situação interessante: o J2ME não mantém a conexão aberta para Inputs e OutPuts.
Em todos os exemplos que eu achei, eu tenho que criar a conexão atravéz do Helper Connector, abrir o Input e OutPut, postar o que quiser mandar para o servidor no Output e ficar esperando com um while no Input até que toda a informação vinda do servidor seja descarregada.
A minha dúvida é: Eu não consigo manter esse tunel aberto? para cada vez que eu quiser alguma coisa do servidor, o Cliente é que tem que requisitar? Eu sei que dá pra fazer fila de mensagens, e a cada requisição a fila é transferida, etc. mas eu estou achando que isso vai consumir recursos que um aparelho real(descartando o emulador) não possui.
A conexão fica aberta pelo tempo que a operadora quiser ou a situação atual da rede suportar. Ponto.
É lógico que elas não tem interesse que você fique minutos ou horas conectados pois isto gera problema de faixa de IP. Cada vez que um cel se conecta a rede, a ele se atribui temporariamente um IP e lógico, menos 1 IP na faixa de endereço da operadora fica disponível para outros usuários.
Imagina se todo mundo inventa de fazer aplicação de push-email ? Táva tudo mundo ferrado…
Concordo com o que você disse. Realmente é uma questão de restringir o consumo de banda.
Mas a minha dúvida é um pouco mais técnica, ou seja, existe uma forma de abrir o tunel e mantê-lo aberto trafegando de um lado para o outro? porque todos os exemplos que encontrei eles fazem uma unica requisição e aguardam a resposta, e quando esta chega tudo é fechado.
[quote=joaoneto]Concordo com o que você disse. Realmente é uma questão de restringir o consumo de banda.
Mas a minha dúvida é um pouco mais técnica, ou seja, existe uma forma de abrir o tunel e mantê-lo aberto trafegando de um lado para o outro? porque todos os exemplos que encontrei eles fazem uma unica requisição e aguardam a resposta, e quando esta chega tudo é fechado.
Obrigado pela atenção.[/quote]
Você mesmo tem a resposta. A forma é não fechar o fluxo e pronto.
Quando vc trabalha com fluxos, você pode ter o comportamento bloqueante ou não-bloqueante…algo que todo mundo que já estudou socket sabe que é assim.
Diz-se bloqueante o comportamento de um método que quando chamado para te retornar algo do fluxo, só vai retornar o controle a quem chamou após os dados aparecerem.
Diz-se não-bloqueante o comportamento de um método que quando chamado, retorna imediatamente a quem chamou independente se tem ou não dados.
Você vai ter um loop que fica lendo do fluxo e ele só lê quando existe dados, por isto você tem a opção de que a leitura seja bloqueante. Se houver erro no fluxo, graciosamente o loop será encerrado e logo em seguida vc faz as finalizações necessárias (closes…,nulls…,etc).
Mestre boone obrigado pelas respostas.
Acho que vou então tentar encontrar uma forma do fluxo ficar aberto, porque por exemplo, para enviar algo ao servidor, eu tenho que abrir o Output, gravar nele e fechar. Sem fechar ele não envia. Já o caso do Input eu notei que é diferente mesmo, ele não precisa ser fechado para ficar recebendo.
Vou fazer mais alguns experimentos, suas respostas me ajudaram a dar uma “clareada” no que preciso fazer.
[quote=joaoneto]Mestre boone obrigado pelas respostas.
Acho que vou então tentar encontrar uma forma do fluxo ficar aberto, porque por exemplo, para enviar algo ao servidor, eu tenho que abrir o Output, gravar nele e fechar. Sem fechar ele não envia. Já o caso do Input eu notei que é diferente mesmo, ele não precisa ser fechado para ficar recebendo.
Vou fazer mais alguns experimentos, suas respostas me ajudaram a dar uma “clareada” no que preciso fazer.
Obrigado.[/quote]
Estranho vc precisar fechar para ir enviando…tem certeza que vc está usando o método flush() para forçar o envio sem precisar fechar o fluxo ?
Sim, eu tentei com o Flush() pra ver se funcionava, mas não deu.
Pode ser alguma configuração extra que eu devo fazer. No exemplo que encontrei no site da SUN ele efetua estas:
client.setSocketOption(DELAY, 0);
client.setSocketOption(KEEPALIVE, 0);
Mas já descobri que o KEEPALIVE deve ser 1 para manter a conexão até o limite de Timeout.
Para referência segue o link:http://developers.sun.com/mobility/midp/articles/midp2network/
[quote=joaoneto]Sim, eu tentei com o Flush() pra ver se funcionava, mas não deu.
Pode ser alguma configuração extra que eu devo fazer. No exemplo que encontrei no site da SUN ele efetua estas:
client.setSocketOption(DELAY, 0);
client.setSocketOption(KEEPALIVE, 0);
Mas já descobri que o KEEPALIVE deve ser 1 para manter a conexão até o limite de Timeout.
Para referência segue o link:http://developers.sun.com/mobility/midp/articles/midp2network/
Obrigado.[/quote]
Posta o código para darmos uma olhada.
Não tá fazendo muito sentido este problema que você tá passando, pois senão não daria certo usar SOCKET para ficar conversando usando um protocolo X (Ex: POP3) com um servidor, por exemplo. Vários protocolos são baseados em COMANDO->RESPOSTA, e portanto é fundamental poder ir enviando, recebendo, enviando, recebendo e por ai vai.
Olha quando voce tenta ler o Input, enquanto nao tiver algo la ,a execuçao nao sai dessa linha de codigo. Entao eu sugiro que voce crie um form,em vez de InputStream e OutputStream use DataInputStream e DataOutputStream,para enviar use o metodo writeUTF() do Output (Strings Utf8) e para ler use readUTF() do Input detro de uma thread para esperar por mensagens assim o resto do aplicativo vai continuar rodando .Chama o metodo aguardaMensagens somente uma vez assim q abrir o DIS e DOS.
Espero ter ajudado .
Eu acabei de fazer uma chat por bluetooth e descobri que IStream e OStream so funcionam no emulador.
[quote]java.io.EOFException
at java.io.DataInputStream.readFully(), bci=45
at java.io.DataInputStream.readUTF(), bci=25
at java.io.DataInputStream.readUTF(DataInputStream.java:547)
at DeploySocket.SocketController$1.run(SocketController.java:97)[/quote]
Tenta isso no cliente pode ter erros é que eu to com um celular e esse codigo ta no meu computador.
DataInputStream dIS;
/*esse é o metodo runCliente chame ele assim q voce quiser iniciar a conexao*/
public void runClient(){
new Thread(){
public void run(){
conectado=false;
while(!conectado){
try{
SocketConnection conn=(SocketConnection)Connector.open(url);
//Conectado
dIS=conn.OpenDataInputStream();
DataOutputStream dOS=conn.OpenDataOutputStream();
//Conexao aberta
dOS.writeUTF("0:OK");
dOS.flush();
//Chama o metodo q cria a thread q espera pela mensagem
aguardaMsgs();
conectado=true;
//para a execucao da Thread
}catch(Exception ex){
ex.printStackTrace();
}
}.start();
}
public void aguardaMsgs(){
new Thread(){
public void run(){
try{
String mensagem=dIS.readUTF();
/*faz o que voce quiser com a mensagem e se for receber outra ou mais mensagens coloca esse try dentro de um while*/
}catch(Exception ex){
ex.printStackTrace();
}
}.start();
}
Cara voce chega a conectar o celular ao computador ?.
To querendo testar com dois celulares mais so tenho internet nesse que eu to e no computador.
Eu vou tentar novamente, mas o modelo que você me enviou está bem parecido com o que eu estou fazendo.
Eu ainda não testei com nenhum aparelho, estou no emulador ainda.
Putz levei um puxão de orelha do Stallone Cobra (O Algoritimo ruim é uma doença, e eu sou a cura!!) hauhauahuahauhauah !!
Eu peço desculpas pelas “badecagens” como dizemos aqui em minas, mas tá sendo bom, eu to aprendendo bastante.
Meu código funcionou amigos, o problema não eram só os Loops e Threads, achei algumas coisas erradas no server.
Estou fazendo um código mais enxuto aqui e vou postar ele assim que estiver pronto.
Obrigado a todos pela atenção.
PS: Meu código já estava dentro de uma thread, dentro da principal do GameCanvas, por isso ela não apareceu no código que postei. Mas fica a dica, pq funcionou melhor sendo individual.
Só acho que vc não deu tanta importância aos comentários dos artigos que leu onde citava o uso de Thread.
Quanto a solução, viu que ela é possível ?!!! Nada como ter o esforço recompensado. Vc lutou e conseguiu. Não desanimou. É assim q tem que ser perante as adversidades.