A função Push de mensagem concluída pelo WebSocket e Java é usada pelo servidor tomcat7.0. Algumas coisas são consideradas por você, e eu não sei se são apropriadas ou inadequadas. Por favor, me perdoe e aponte -os.
Em termos simples, o cliente A pode enviar mensagens para o cliente B, mas há muitos lugares que podem ser expandidos.
por exemplo
1. Se, depois de ingressar no banco de dados, quando a enviar a mensagem, o cliente B não estiver online, o servidor armazenará a mensagem no banco de dados. Depois que o cliente B estiver online, a mensagem será recuperada e enviada ao cliente B.
2. O servidor também pode enviar mensagens para qualquer cliente.
A captura de tela do efeito de execução do programa é a seguinte (testada em Chrome, Sogou e Firefox): o código será dado no final
Primeiro, abrimos um navegador e exibimos para inserir seu nome. Aqui eu entro Soar
Ao abrir o segundo navegador, aqui eu entro na Bill
Isto é se eu enviar olá Bill, sou Soar para Bill, clique em Enviar
Você pode ver em outro navegador
WebSocket
1. O que é WebSocket?
O WebSocket é uma tecnologia gerada para resolver a comunicação em tempo real entre clientes e servidores. A essência é criar uma conexão TCP para a troca de dados após o handshaking através do protocolo HTTP/HTTPS.
Depois disso, o servidor e o cliente se comunicam em tempo real através dessa conexão TCP.
2. Vantagens do WebSocket
No passado, implementamos a tecnologia push, usando a pesquisa. No intervalo de tempo característico, o navegador emite automaticamente uma solicitação e retira ativamente as mensagens do servidor. Nesse caso, precisamos enviar solicitações constantemente para o servidor. No entanto, o cabeçalho da solicitação HTTP é muito longo, e os dados contidos nela podem ser apenas um valor pequeno, que ocupará muita largura de banda e recursos do servidor. Ele consumirá muita largura de banda e recursos do servidor.
A melhor coisa da API do WebSocket é que o servidor e o cliente podem pressionar as informações a qualquer momento dentro de um determinado intervalo de tempo. Após estabelecer a conexão, o servidor pode transmitir ativamente dados ao cliente.
Além disso, as informações do cabeçalho trocadas entre o servidor e o cliente são muito pequenas.
O WebSocket não se limita à comunicação no modo AJAX (ou XHR), porque a tecnologia AJAX exige que os clientes iniciem solicitações, enquanto servidores e clientes da WebSocket podem pressionar as informações;
Para uma introdução detalhada às mensagens Ajax, Comet, WebSocket e WebSocket, você pode consultar http://www.shaoqun.com/a/54588.aspx web design] Ajax, Comet e WebSocket.
Se eu tiver tempo no futuro, vou escrever.
3. Como usar o WebSocket
Cliente
Em um navegador que suporta o WebSocket, depois de criar o soquete. Você pode responder aos soquetes através de quatro eventos: ONOPEN, ONMESSAGE e ONCLOSE, isto é, OnError.
Um exemplo simples
var ws = novo websocket (ws: // localhost: 8080); ws.onopen = function () {console.log (aberto); ws.send (hello);}; ws.onmessage = function (evt) {console.log (evt.data)}; ws.onclose = function (evt) {console.log (websocketcled!);}; ws.onerror = function (function) {console.Log (1.Var ws = novo websocket (ws: // localhost: 8080);
Para se inscrever em um objeto WebSocket, os parâmetros são o endereço do servidor que precisa ser conectado. Assim como o protocolo HTTP, o URL do protocolo WebSocket começa com WS: //, e o Protocolo Secure WebSocket começa com WSS: //.
ws.send (olá);
Usado para enviar mensagens para o servidor
2.ws.onopen = function () {console.log (aberto)};
Quando o WebSocket for criado com sucesso, o evento Onopen será acionado
3.ws.onmessage = function (evt) {console.log (evt.data)};
Quando o cliente recebe uma mensagem enviada pelo servidor, o evento OnMessage será acionado. O parâmetro evt.data contém os dados transmitidos pelo servidor.
4.WS.Onclose = function (EVT) {console.log (websocketcled!); };
Quando o cliente recebe uma solicitação para fechar a conexão enviada pelo servidor, o evento OCLOSE é acionado
5.WS.ONERROR = function (EVT) {console.log (webSocketError!); };
Se a conexão, o processamento, o recebimento e o envio de dados falharem, o evento ONERROR será acionado
Podemos ver que todas as operações são acionadas por eventos, para que a interface do usuário não bloqueie, permitindo que a interface do usuário tenha um tempo de resposta mais rápido e uma melhor experiência do usuário.
Lado do servidor
Atualmente, existem muitos softwares de servidor que suportam o WebSocket, como Node.js, Jetty, Tomcat, etc.
Aqui estou usando Tomat 7.0 e Eclipse4.2
Tomcat, use o websocket primeiro para importar o frasco relevante
As classes relacionadas ao WebSocket fornecidas pelo TomCat7 estão todas localizadas no pacote org.apache.catalina.websocket (a implementação do pacote org.apache.catalina.websocket está contida no arquivo catalina.jar.Jar
Aqui apenas importamos todo o tomcat
No caminho de construção-> configure Build Path-> Librarise-> Adicionar biblioteca-> servidor Runtime-> Apache Tomcat v7.0
imagem
Além disso, importe os seguintes pacotes
importar org.apache.catalina.websocket.messageInbound;
importar org.apache.catalina.webSocket.streamInbound;
importar org.apache.catalina.websocket.wsoutbound;
importar org.apache.catalina.webSocket.websocketServlet;
Precisamos de duas aulas
O primeiro é usado para lidar com solicitações do WebSocket
O segundo é usado para lidar com cada tarefa específica do WebSocket
A primeira categoria
classe pública SocketServer estende WebSocketServlet {
private estático final serialversionUid = 1L;
//…
@Override
Streaminbound protegido CreateWebSocketInBound (String arg0,
HttpServletRequest arg1) {
// TODO Method Stub
retornar novos chatwebsocket (usuários);
}
}
Este servlet herda do WebSocketServlet e implementa o método CreateWebSocketInbound. Este método retorna uma instância da segunda classe.
A segunda categoria
classe pública chatwebsocket estende MessageInbound {
@Override
OntextMessage protegido (mensagem de charbuffer) lança ioexception {
}
@Override
Onopen de vazio protegido (saída WSOUTBOUND) {
}
@Override
Onclose do vazio protegido (status int) {
}
@Override
Void protegido onbinarymessage (bytebuffer arg0) lança ioexception {
}
// o resto é apenas um pouco
}
OtextMessage do vazio protegido (mensagem de charbuffer) lança ioexception {}
Resposta da mensagem de texto
Void protegido onbinarymessage (bytebuffer arg0) lança ioexception {}
Resposta binária da mensagem
Onopen de vazio protegido (saída WSOUTBOUND) {}
Eventos acionados pelo estabelecimento de uma conexão
Void protegido Onclose (status int) {}
Eventos disparados ao fechar a conexão
4. Código do programa
parte html
<! Doctype html>
<html>
<head>
<meta charset = utf-8>
<script type = text/javascript src = js/jQuery.js> </script>
<script type = text/javascript src = js/socket.js> </script>
<title> unt intitulado Documento </title>
</head>
<idioma do script = javascript>
</script>
<Body>
<tabela>
<tr>
<td> mensagem </td>
<Td> <Tipo de entrada = ID do texto = Mensagem> </td>
</tr>
<tr>
<Td> Nome </td>
<Td> <Tipo de entrada = ID do texto = OtherName> </td>
</tr>
<tr>
<Td> <ID de entrada = sendButton type = Button value = envio onclick = clique em Disabled = true>
</input> </td>
</tr>
</tabela>
<Cript>
</script>
</body>
</html>
JS Part (sem explicação sobre a parte do jQuery)
var usuário nome = window.prompt (insira seu nome :);
document.write (bem -vindo <p id =/nome de usuário/>+nome de usuário+</p>);
if (! window.websocket && window.mozwebsocket)
window.websocket = window.mozwebSocket;
if (! window.websocket)
alerta (sem suporte);
var ws;
$ (document) .ready (function () {
$ (#sendButton) .attr (desativado, false);
$ (#sendButton) .Click (SendMessage);
startwebsocket ();
})
função sendMessage ()
{
var otherName = $ (#OtherName) .val ();
var msg = msg/t+nome de usuário+_+outro nome+_+$ (#message) .val ();
send (msg);
}
função envia (dados)
{
console.log (send:+dados);
ws.send (dados);
}
função startwebsocket ()
{
ws = novo websocket (ws: // + location.host +/websocket/socketServer);
ws.onopen = function () {
console.log (sucesso aberto);
$ (#sendButton) .attr (desativado, false);
};
ws.onmessage = function (evento)
{
console.log (receba:+event.data);
Handledata (event.data);
};
ws.onclose = function (evento) {
console.log (o soquete do cliente foi fechado, evento);
};
}
função manipulada (dados)
{
var vals = data.split (/t);
var msgtype = vals [0];
Switch (msgtype)
{
Nome do caso:
var msg = vals [1];
var mes = nome+/t+msg+_+nome de usuário;
send (mes);
quebrar;
Case msg:
var val2s = vals [1] .split (_);
var de = val2s [0];
var mensagem = val2s [2];
alerta (de+:+mensagem);
quebrar;
padrão:
quebrar;
}
}
Java parte
importar java.io.ioException;
importar java.nio.byteBuffer;
importar java.nio.charbuffer;
importar javax.servlet.http.httpServletRequest;
importar java.util.set;
importar java.util.concurrent.copyonWritearRaySet;
importar org.apache.catalina.websocket.messageInbound;
importar org.apache.catalina.webSocket.streamInbound;
importar org.apache.catalina.websocket.wsoutbound;
importar org.apache.catalina.webSocket.websocketServlet;
classe pública SocketServer estende WebSocketServlet {
private estático final serialversionUid = 1L;
Public Final Set <CHATWebSocket> usuários = novo copywritearraySet <CHATWebSocket> ();
public static int usernumber = 1;
@Override
Streaminbound protegido CreateWebSocketInBound (String arg0,
HttpServletRequest arg1) {
// TODO Method Stub
retornar novos chatwebsocket (usuários);
}
classe pública chatwebsocket estende MessageInbound {
Nome de usuário privado de string;
Conjunto privado <CHATWebSocket> Usuários = novo copywritearrayset <CHATWebSocket> () ;;
public chatwebsocket () {
}
public chatwebsocket (set <atwebsocket> usuários) {
this.Users = usuários;
}
@Override
OntextMessage protegido (mensagem de charbuffer) lança ioexception {
// O que é processado aqui são dados de texto
}
public void onMessage (String Data) {
String [] val1 = data.split (// t);
if (val1 [0] .Equals (nome))
{
String [] val2 = val1 [1] .split (_);
Para (Usuário do ChatwebSocket: Usuários) {
if (user.username.equals (val2 [0])) {
user.UserName = Val2 [1];
}
}
}
caso contrário, se (Val1 [0] .Equals (MSG))
{
String [] val2 = val1 [1] .split (_);
Para (Usuário do ChatwebSocket: Usuários) {
if (user.username.equals (val2 [1])) {
tentar {
CharBuffer Temp = CharBuffer.Wrap (Data);
user.getwsoutBound (). writeTextMessage (temp);
} catch (ioexception e) {
// TODO BLOCO DE CAPAGEM AUTOMAGEM
E.PrintStackTrace ();
}
}
}
}
outro
{
System.out.println (erro);
}
}
@Override
Onopen de vazio protegido (saída WSOUTBOUND) {
// this.connection = conexão;
this.UserName = # + string.valueof (usernumber);
UserNumber ++;
tentar {
String message = nome + /t + this.username;
Buffer de charbuffer = charbuffer.wrap (mensagem);
this.getWsOutBound (). writeTextMessage (buffer);
} catch (ioexception e) {
// TODO BLOCO DE CAPAGEM AUTOMAGEM
E.PrintStackTrace ();
}
usuários.add (this);
}
@Override
Onclose do vazio protegido (status int) {
users.remove (isto);
}
@Override
Void protegido onbinarymessage (bytebuffer arg0) lança ioexception {
}
}
}
explicar
Minha ideia aqui é
1 Ao acessar, cada usuário precisa primeiro inserir seu nome e enviar uma solicitação de conexão ao servidor.
2 Depois que o servidor aceitar a solicitação de conexão do cliente, ele será novo ChatWebSocket (usuários); Para processar essa solicitação e adicioná -la à lista de usuários on -line. No momento, o servidor ainda não conhece o nome do cliente. Ele assumirá um nome para esse usuário, nº 1, e o servidor enviará o nome + /t + #1 para o cliente, qual é o seu nome?
3 Quando o cliente receber esta mensagem, ele saberá que o servidor está se perguntando qual é o nome, para que o cliente envie nome+/t+#1+_+seu próprio nome para o servidor (meu nome é xxx)
4 Depois de receber esta mensagem, o servidor pesquisa na lista de usuários on -line atualmente com base no número 1 e substitui o número 1 pelo nome do cliente, para que o servidor saiba o nome do cliente.
5 Quando o cliente sair, o servidor acionará o evento OCLOSE e o servidor removerá o usuário atual da lista on -line.
Use imagens para desenhar algo assim (desenhado mal, -_- !!)
Código
JS
ws = novo websocket (ws: // + location.host +/websocket/socketServer);
Conecte -se ao servidor
Java
Streaminbound protegido CreateWebSocketInBound (String arg0,
HttpServletRequest arg1) {
// TODO Method Stub
retornar novos chatwebsocket (usuários);
}
Crie um chatwebsocket para lidar com esta solicitação e acionar o evento Onopen do objeto ChatwebSocket
@Override
Onopen de vazio protegido (saída WSOUTBOUND) {
// this.connection = conexão;
this.UserName = # + string.valueof (usernumber);
UserNumber ++;
tentar {
String message = nome + /t + this.username;
Buffer de charbuffer = charbuffer.wrap (mensagem);
this.getWsOutBound (). writeTextMessage (buffer);
} catch (ioexception e) {
// TODO BLOCO DE CAPAGEM AUTOMAGEM
E.PrintStackTrace ();
}
usuários.add (this);
}
Supondo um nome para este cliente, enviando o nome assumido de nome+/t+ ao cliente e adicionando o cliente à lista de clientes atualmente conectados
JS
função manipulada (dados)
{
var vals = data.split (/t);
var msgtype = vals [0];
Switch (msgtype)
{
Nome do caso:
var msg = vals [1];
var mes = nome+/t+msg+_+nome de usuário;
send (mes);
quebrar;
// ………
}
}
Aceite e processe a mensagem enviada pelo servidor e descobri que o servidor perguntou qual é o nome, por isso enviou o nome+/t+o nome assumido+_+para o servidor.
Java
public void onMessage (String Data) {
String [] val1 = data.split (// t);
if (val1 [0] .Equals (nome))
{
String [] val2 = val1 [1] .split (_);
Para (Usuário do ChatwebSocket: Usuários) {
if (user.username.equals (val2 [0])) {
user.UserName = Val2 [1];
}
}
}
// ………
}
Processe e aceite a mensagem enviada pelo cliente e descobri que o cliente respondeu ao seu nome; portanto, pesquise na lista de clientes atualmente conectada com base no nome assumido anteriormente e transforme o pseudônimo no nome real
JS
função sendMessage ()
{
var otherName = $ (#OtherName) .val ();
var msg = msg/t+nome de usuário+_+outro nome+_+$ (#message) .val ();
send (msg);
}
O cliente inicia uma conversa com outra pessoa, e o formato da mensagem é: msg+seu próprio nome+_+nome oposto+_+mensagem
Java
public void onMessage (String Data) {
/// …………
caso contrário, se (Val1 [0] .Equals (MSG))
{
String [] val2 = val1 [1] .split (_);
Para (Usuário do ChatwebSocket: Usuários) {
if (user.username.equals (val2 [1])) {
tentar {
CharBuffer Temp = CharBuffer.Wrap (Data);
user.getwsoutBound (). writeTextMessage (temp);
} catch (ioexception e) {
// TODO BLOCO DE CAPAGEM AUTOMAGEM
E.PrintStackTrace ();
}
}
}
}
/// …………
}
Verifica -se que a mensagem é enviada pelo cliente. De acordo com o nome da outra parte, pesquise na lista de clientes atualmente conectada e envie a mensagem para ele.
JS
função manipulada (dados)
{
var vals = data.split (/t);
var msgtype = vals [0];
Switch (msgtype)
{
///…
Case msg:
var val2s = vals [1] .split (_);
var de = val2s [0];
var mensagem = val2s [2];
alerta (de+:+mensagem);
quebrar;
padrão:
quebrar;
}
}
Verificou -se que era uma mensagem enviada por outro cliente e foi exibida por alerta
Java
@Override
Onclose do vazio protegido (status int) {
users.remove (isto);
}
Descobrindo o cliente saiu, remova o cliente da lista de clientes conectados
Onde melhorar
1. Se o cliente A enviar uma mensagem para B e B não estiver online, a mensagem poderá ser armazenada no banco de dados. Quando B é encontrado online, ele será recuperado do banco de dados e enviado para B.
2 Quando o servidor envia seu nome, ele pode adicionar um mecanismo de tempo limite. Se o cliente não responder ao que é chamado dentro de um determinado período de tempo, o cliente poderá excluir o cliente da lista on -line.