Pergunta

Para implementar um servidor que suporte clientes usando soquetes da web, os servidores mantêm uma conexão HTTP aberta com cada cliente?Como isso pode ser dimensionado?

Quais são os “modelos de programação” na implementação deste tipo de servidor?Ou seja:a maioria dos aplicativos da web possui servlets, etc., que suportam um modelo de tipo connect->request->response->close.Já com web sockets a conexão permanece aberta indefinidamente.

Foi útil?

Solução

Geralmente você precisa trabalhar em um assíncrono modelo para que essas conexões duradouras funcionem.Existem diversas técnicas diferentes para realizar E/S assíncrona;todos eles têm suas vantagens e desvantagens.

Um que já deve ser familiar para quem já trabalhou com JavaScript e AJAX é o modelo de retorno de chamada;no qual você envia uma solicitação e instala um retorno de chamada a ser chamado quando for concluído.É assim XMLHTTPRequest funciona, sem bloquear todas as outras páginas enquanto aguardam a conclusão da solicitação de uma página.É também assim que Torcido A estrutura de rede Python funciona, embora possa chamar métodos em objetos ou funções de retorno de chamada, dependendo das interfaces que você usa.

Outro modelo poderoso é o Erlang A abordagem de estilo, chamada de modelo Ator, tem muitos processos leves (como threads, mas sem estado compartilhado), cada um dos quais se comunica entre si por meio de mensagens assíncronas.O tempo de execução Erlang foi implementado para tornar a geração de milhares de processos muito eficiente;então você pode ter apenas um processo para cada conexão e fazer com que eles enviem mensagens para outros processos que implementam o back-end do seu aplicativo.Os processos Erlang também podem ser agendados automaticamente em vários threads de sistema operacional, para aproveitar ao máximo os sistemas multi-core. ejabberd, um servidor Jabber popular (um protocolo de bate-papo, que requer muitas conexões abertas de longa duração), é implementado em Erlang, assim como o Sistema de bate-papo do Facebook.

O novo Vá para o idioma do Google usa uma abordagem semelhante, mais próxima do modelo Communicating Sequential de Hoare do que do modelo Actor de Erlang, mas que tem muitas semelhanças.

No Mac OS X 10.6, a Apple introduziu Despacho Grande Central, junto com blocos (essencialmente fechamentos) em C, C++ e Objective-C.Isso permite algo como o modelo de retorno de chamada orientado a eventos no estilo AJAX ou Twisted, mas com filas gerenciadas explicitamente que são executadas sequencialmente para gerenciar o acesso a recursos compartilhados em um ambiente multithread e multinúcleo.Twisted e JavaScript executam thread único e, portanto, só podem tirar proveito de um único núcleo, a menos que você use vários processos de sistema operacional, o que pode ser bastante pesado e aumentar os custos de comunicação entre eles.

Depois, há os modelos mais tradicionais, como o Unix select função, ou o mais moderno e capaz epoll ou kqueue().Nestes, você geralmente tem um loop principal em seu programa, que configura vários eventos a serem observados (E/S de rede retorna mais alguns dados, E/S de arquivo retorna mais dados, uma nova conexão de rede é feita, etc.) e, em seguida, chama uma chamada de sistema que bloqueia até que um desses eventos ocorra. Nesse ponto, você verifica qual deles ocorreu e, em seguida, trata-o adequadamente.Essas chamadas de sistema geralmente são usadas para fornecer estruturas de nível superior descritas acima.

Para uma visão geral muito boa da impressionante variedade de opções disponíveis (com foco nas abordagens Unix mais tradicionais e de nível inferior), consulte O problema C10K, um levantamento de diferentes técnicas para ajudar a lidar com 10.000 conexões simultâneas de uma só vez.Também possui uma boa lista de bibliotecas C e C++ para abstrair as várias APIs disponíveis, como evento libe.

Uma opção final, é claro, é usar um processo ou thread de sistema operacional para cada conexão.O problema é que os processos são muito pesados ​​e até mesmo os threads são bastante pesados ​​em comparação com muitas dessas opções.Em geral, para obter o melhor desempenho, você desejaria ter um processo ou thread por CPU, cada um usando uma API de E/S assíncrona para descobrir quando precisa fazer trabalho e, em seguida, despachar esse trabalho para um dos vários objetos ou retornos de chamada que foram registrados para lidar com conexões, ou um dos vários processos leves do estilo Erlang que estão aguardando uma mensagem, ou algo do tipo.

Como observação lateral, a conexão em web sockets não são conexões HTTP, mas um novo protocolo, o protocolo websocket, embora você possa usar a mesma porta do HTTP e atualizar uma conexão HTTP para um soquete da Web para ser compatível com as regras de firewall existentes.

Outras dicas

De um modo geral, você deve usar o WebSockets com implementações de servidor personalizadas projetadas para lidar com a carga de uma maneira leve. Esses servidores já existem para conexões de cometa de longa duração e similares.

Ele difere do HTTP, pois cada solicitação / resposta subsequente não precisa ser envolvida em uma mensagem HTTP com cabeçalhos HTTP. Portanto, os aplicativos em tempo real não precisariam da sobrecarga de parsir cabeçalhos. Após o aperto de mão inicial do tipo HTTP, ele se comporta basicamente como um soquete TCP regular.

Isso poderia ser modelado com servlets, mas seria necessário distinguir entre a solicitação inicial (com todos os cabeçalhos) e a caixa de diálogo bidirecional subsequente cujo formato é arbitrário na maior parte.

Dê uma olhada no HTML 5 WebSockets implementados no Tornado WebServer:http://bret.appspot.com/entry/web-sockets-in-tornado

Ainda não brinquei com este módulo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top