Algumas ótimas respostas de outras pessoas que cobrem muito terreno. Aqui está um pouco mais.
A única vantagem do WebSockets em relação a plug-ins como Java Applets, Flash ou Silverlight é que o WebSockets é nativamente incorporado aos navegadores e não depende de plug-ins.
Se com isso você quer dizer que pode usar Java Applets, Flash ou Silverlight para estabelecer uma conexão de soquete, então sim, isso é possível. No entanto, você não vê isso implantado no mundo real com muita frequência por causa das restrições.
Por exemplo, os intermediários podem e encerram esse tráfego. O padrão WebSocket foi projetado para ser compatível com a infraestrutura HTTP existente e, portanto, é muito menos suscetível a interferências de intermediários, como firewalls e proxies.
Além disso, o WebSocket pode usar as portas 80 e 443 sem a necessidade de portas dedicadas, novamente graças ao design do protocolo para ser o mais compatível possível com a infraestrutura HTTP existente.
Essas alternativas de soquete (Java, Flash e Silverlight) são difíceis de usar com segurança em uma arquitetura de origem cruzada. Assim, as pessoas que tentam usá-las com origem cruzada toleram as inseguranças em vez de se esforçarem para fazê-lo com segurança.
Eles também podem exigir a abertura de portas "não padronizadas" adicionais (algo que os administradores detestam fazer) ou arquivos de políticas que precisam ser gerenciados.
Em resumo, o uso de Java, Flash ou Silverlight para conectividade de soquete é problemático o suficiente para que você não o veja implantado em arquiteturas sérias com muita frequência. Flash e Java têm esse recurso há provavelmente pelo menos 10 anos, e ainda assim não é predominante.
O padrão WebSocket foi capaz de começar com uma nova abordagem, tendo em mente essas restrições e, esperançosamente, tendo aprendido algumas lições com elas.
Algumas implementações do WebSocket usam Flash (ou possivelmente Silverlight e / ou Java) como substituto quando a conectividade do WebSocket não pode ser estabelecida (como ao executar em um navegador antigo ou quando um intermediário interfere).
Embora algum tipo de estratégia de fallback para essas situações seja inteligente, mesmo necessário, a maioria das pessoas que usam Flash et al sofrerá com as desvantagens descritas acima. Não precisa ser assim - existem soluções alternativas para obter conexões seguras com origem cruzada usando Flash, Silverlight, etc. - mas a maioria das implementações não faz isso porque não é fácil.
Por exemplo, se você confiar no WebSocket para uma conexão de origem cruzada, isso funcionará bem. Mas se você executar em um navegador antigo ou um firewall / proxy interferir e confiar no Flash, por exemplo, como seu substituto, será difícil fazer a mesma conexão de origem cruzada. A menos que você não se importe com segurança, é claro.
Isso significa que é difícil ter uma arquitetura unificada única que funcione para conexões nativas e não nativas, a menos que você esteja preparado para trabalhar bastante ou seguir uma estrutura que tenha feito isso bem. Em uma arquitetura ideal, você não notaria se as conexões eram nativas ou não; suas configurações de segurança funcionariam nos dois casos; suas configurações de cluster ainda funcionariam; seu planejamento de capacidade ainda seria válido; e assim por diante.
A única vantagem do WebSockets sobre o streaming http é que você não precisa se esforçar para "entender" e analisar os dados recebidos.
Não é tão simples quanto abrir um fluxo HTTP e relaxar, pois seus dados fluem por minutos, horas ou mais. Diferentes clientes se comportam de maneira diferente e você precisa gerenciar isso. Por exemplo, alguns clientes armazenam em buffer os dados e não os liberam no aplicativo até que algum limite seja atingido. Pior ainda, alguns não passarão os dados para o aplicativo até que a conexão seja fechada.
Portanto, se você estiver enviando várias mensagens para o cliente, é possível que o aplicativo cliente não receba os dados até que 50 mensagens de dados sejam recebidas, por exemplo. Isso não é muito em tempo real.
Embora o streaming HTTP possa ser uma alternativa viável quando o WebSocket não estiver disponível, não é uma panacéia. Ele precisa de um bom entendimento para funcionar de maneira robusta nas áreas remotas da Web em condições reais.
Faltam outras diferenças significativas?
Há mais uma coisa que ninguém mencionou ainda, então vou falar disso.
O protocolo WebSocket foi projetado para ser uma camada de transporte para protocolos de nível superior. Embora você possa enviar mensagens JSON ou o que não é diretamente por uma conexão WebSocket, ele também pode transportar protocolos padrão ou personalizados.
Por exemplo, você pode fazer AMQP ou XMPP sobre WebSocket, como as pessoas já fizeram. Portanto, um cliente pode receber mensagens de um broker AMQP como se estivesse conectado diretamente ao próprio broker (e, em alguns casos, é).
Ou, se você já possui um servidor com algum protocolo personalizado, pode transportá-lo pelo WebSocket, estendendo esse servidor de back-end para a Web. Geralmente, um aplicativo existente bloqueado na empresa pode ampliar seu alcance usando o WebSocket, sem precisar alterar nenhuma infraestrutura de back-end.
(Naturalmente, você poderá fazer tudo isso de forma segura, portanto verifique com o fornecedor ou o provedor WebSocket.)
Algumas pessoas se referiram ao WebSocket como TCP para a Web. Como o TCP transporta protocolos de nível superior, o mesmo ocorre com o WebSocket, mas de uma maneira compatível com a infraestrutura da Web.
Portanto, embora o envio de mensagens JSON (ou o que seja) diretamente pelo WebSocket seja sempre possível, é preciso considerar também os protocolos existentes. Porque para muitas coisas que você deseja fazer, provavelmente existe um protocolo que já foi pensado para isso.
Sinto muito se estou re-perguntando ou combinando muitas das perguntas que já estão no SO em uma única pergunta, mas só quero fazer todo o sentido de todas as informações disponíveis no SO e na Web sobre esses conceitos.
Esta foi uma ótima pergunta, e as respostas foram todas muito informativas!