1. Análise de abertura
A partir de hoje, vamos aprender em detalhes em módulos específicos. Este artigo é o terceiro artigo desta série. Os dois primeiros artigos são baseados principalmente na teoria. Eu acredito que no estudo dos dois primeiros artigos,
Eu também tenho um entendimento básico dos nodejs, está tudo bem! ! ! Bata enquanto o ferro estiver quente, vamos continuar carregando nodejs até o fim. Bem, sem dizer muita bobagem, vá diretamente ao tópico de hoje "módulo net". Então, como "net" deve entender isso?
Para que serve? ( Net pode ser usado para criar servidores de soquete ou clientes de soquete. Os dois módulos mais básicos para a comunicação de dados do NodeJS são Net e HTTP. O primeiro é um encapsulamento baseado em TCP, enquanto o último é essencialmente uma camada de TCP, mas fez muito encapsulamento de dados, que consideramos uma camada de apresentação).
Aqui nos referimos ao código -fonte no NodeJS "http.js":
Não é difícil ver pela figura que o HTTPServer herda a classe Net, possui recursos de comunicação relacionados e fez mais encapsulamento de dados, que consideramos uma camada de representação mais avançada.
Conhecimento estendido (o seguinte é o código -fonte de "herda"):
A cópia do código é a seguinte:
exports.Irits = function (cTor, superctor) {
ctor.super_ = superctor;
ctor.prototype = object.create (superctor.prototype, {
Construtor: {
Valor: CTOR,
enumerável: falso,
gravável: verdadeiro,
Configurável: Verdadeiro
}
});
};
A função é realizar herança e reutilização.
Acabei de dar uma breve visão geral, que contém alguns conceitos comumente usados. Aqui está uma breve introdução à popularização de conceitos:
(1) TCP/IP ---------- TPC/IP Protocol é um protocolo de camada de transporte, que resolve principalmente como os dados são transmitidos na rede.
(2), soquete ----- SOCKET é o encapsulamento e a aplicação do protocolo TCP/IP (nível do programa).
(3), http ------ HTTP é um protocolo da camada de aplicativo, que resolve principalmente como envolver dados.
(4) O modelo de rede de sete camadas ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Para resumir: o soquete é um encapsulamento do protocolo TCP/IP. O próprio soquete não é um protocolo, mas uma interface de chamada (API).
Isso forma algumas das interfaces funcionais mais básicas que conhecemos, como criar, ouvir, conectar, aceitar, enviar, ler e escrever etc.
O TCP/IP é apenas uma pilha de protocolo, assim como o mecanismo operacional do sistema operacional, ele deve ser implementado em detalhes e também fornece interfaces operacionais externas.
De fato, o TCP da camada de transporte é baseado no protocolo IP da camada de rede, e o protocolo HTTP da camada de aplicação é baseado no protocolo TCP da camada de transporte. O soquete em si não é um protocolo. Como mencionado acima, ele fornece apenas uma interface para programação TCP ou UDP.
Segundo, experimente
Ok, temos o conceito, vamos dar um exemplo:
1. Crie server.js
A cópia do código é a seguinte:
var net = requer ('net');
var server = net.createServer (function (c) {// ouvinte de conexão
console.log ("servidor conectado");
c.on ("end", function () {
console.log ("O servidor foi desconectado");
});
C.Write ("Olá, BigBear!/R/N");
c.pipe (c);
});
Server.Listen (8124, function () {// ouvindo ouvinte
console.log ("servidor limitado");
});
2. Crie client.js
A cópia do código é a seguinte:
var net = requer ('net');
var client = net.connect ({
Porta: 8124
}, function () {// conectar o ouvinte
console.log ("cliente conectado");
client.write ('Olá, baby!/r/n');
});
client.on ("dados", função (dados) {
console.log (data.toString ());
client.end ();
});
client.on ("end", function () {
console.log ("Desconecção do cliente");
});
Vamos analisar:
Servidor ------ net.createServer cria um serviço TCP. Este serviço está ligado (server.listen) na porta 8124. Depois de criar o servidor, vemos uma função de retorno de chamada.
Ao chamar a função acima, um parâmetro também é uma função e aceita soquete, um tubo construído por outros métodos e sua função é para interação de dados.
O tubo precisa ser recebido pelo cliente para estabelecê -lo. Se não houver acesso ao cliente ao servidor neste momento, este soquete não existirá.
Como o nome sugere,客户端------net.connect está conectado ao servidor. O primeiro parâmetro é um objeto. A porta (porta) está definida como 8124, que é a porta para a qual nosso servidor ouve. Como o parâmetro do host não está definido, o padrão é localhost (local).
No servidor, o soquete é uma extremidade do pipeline e, no cliente, o próprio cliente é uma extremidade do pipeline. Se vários clientes estiverem conectados ao servidor, o servidor criará vários soquetes e cada soquete corresponde a um cliente.
Resultados em execução:
3. Introdução ao caso
(1) O código a seguir é apenas o servidor que emitiu um texto para o cliente para concluir a comunicação unidirecional do servidor para o cliente.
A cópia do código é a seguinte:
// sever-> comunicação unidirecional do cliente
var net = requer ('net');
var chatserver = net.createServer ();
ChatServer.on ('Connection', function (cliente) {
client.write ('oi!/n'); // O servidor produz informações para o cliente e usa o método write ()
client.write ('tchau!/n');
client.end (); // O servidor termina a sessão
});
ChatServer.Listen (9000);
Teste de telnet: telnet127.0.0.1: 9000
Depois de executar o Telnet, conecte -se ao ponto de serviço, feedback os caracteres do HI! Bye!, E termina imediatamente o programa do servidor e encerre a conexão.
E se quisermos que o servidor se conecte às informações ao cliente?
Você pode ouvir o evento Server.Data e não abortar a conexão (ou ele encerrará imediatamente as mensagens do cliente que não podem ser aceitas).
(2), ouça o evento Server.data e não abortar a conexão (caso contrário, as mensagens do cliente não poderão ser aceitas imediatamente).
A cópia do código é a seguinte:
// com base no primeiro cliente de implementação-> sever comunicação, que é uma comunicação bidirecional
var net = requer ('net');
var chatserver = net.createServer (),
clientelist = [];
ChatServer.on ('Connection', function (cliente) {
// JS pode adicionar livremente propriedades aos objetos. Aqui adicionamos um atributo personalizado do nome para indicar em qual cliente (o endereço + a porta do cliente é baseado)
client.name = client.remoteAddress + ':' + client.remoteport;
client.write ('oi' + client.name + '!/n');
clientelist.push (cliente);
client.on ('dados', função (dados) {
transmissão (dados, cliente); // aceita informações do cliente
});
});
Função Broadcast (mensagem, cliente) {
for (var i = 0; i <clientList.length; i+= 1) {
if (client! == ClientList [i]) {
ClientList [i] .Write (client.name + "diz" + mensagem);
}
}
}
ChatServer.Listen (9000);
O acima é um código completo? Dissemos que há outro problema que não foi levado em consideração: ou seja, uma vez que um cliente sai, ele permanece na lista de clientes, o que é obviamente um ponteiro nulo.
(3) Lista de clientes do processo
A cópia do código é a seguinte:
ChatServer.on ('Connection', function (cliente) {
client.name = client.remoteAddress + ':' + client.remoteport
client.write ('oi' + client.name + '!/n');
ClientList.push (cliente)
client.on ('dados', função (dados) {
transmissão (dados, cliente)
})
client.on ('end', function () {
clientList.splice (clientlist.indexOF (cliente), 1); // Exclua o elemento de fórmula na matriz.
})
})
O NodeTCPAPI nos forneceu um evento final, ou seja, quando o cliente aborta a conexão com o servidor.
(4) otimize a transmissão
A cópia do código é a seguinte:
Função Broadcast (mensagem, cliente) {
var limpo = []
for (var i = 0; i <clientList.length; i+= 1) {
if (client! == ClientList [i]) {
if (clientlist [i] .Writável) {// Verifique se os soquetes são graváveis primeiro
ClientList [i] .Write (client.name + "diz" + mensagem)
} outro {
Cleanup.push (clientelist [i]) // Se não for gravável, colete e destrua. Antes da destruição, o soquete.Destroy () deve ser destruído pela API.
ClientList [i] .Destroy ()
}
}
} // Remova os nós mortos fora do loop de gravação para evitar o índice de lixeira
for (i = 0; i <limpeza.length; i+= 1) {
ClientList.splice (clientlist.indexOF (limpeza [i]), 1)
}
}
Observe que, uma vez que o "final" não for acionado, ocorrerá uma exceção, portanto o trabalho de otimização será realizado.
(5) Netapi também fornece um evento de erro para capturar exceções do cliente
A cópia do código é a seguinte:
client.on ('erro', função (e) {
console.log (e);
});
Quatro, vamos resumir
1. Entenda os conceitos relevantes do começo
2. Entenda a relação entre http e módulos líquidos
3. Com base nos exemplos deste artigo, consulte as APIs relevantes para a prática.
4. Idéias de comunicação entre o cliente e o servidor
5. Se você estiver interessado, pode melhorar o exemplo dessa sala de bate -papo