Pergunta

Estou criando uma interface de usuário Silverlight 2 para um instrumento remoto. Há dois usuários simultâneos em diferentes locais, interagindo com o instrumento (operador no instrumento e remoto cientista) e qualquer número de usuários observador não interagir com ele, apenas observando. No entanto, sempre que um dos dois utilizadores activos muda algo estas alterações devem ser reflectido imediatamente nas interfaces de todos os utilizadores, por exemplo panning ou ampliar uma imagem ou anotação ou selecionar parte de uma imagem, adicionar itens a uma coleção exibida em uma caixa de listagem. Dentro do cliente eu uso coleções observáveis ??que refletem facilmente as alterações feitas por esse usuário, mas é mais difícil de ver as alterações feitas por outro usuário. Eu posso pesquisar para alterações de cada cliente, mas algo como notificações push seria melhor. Tenho extensivamente Googled para exemplos, mas não encontrei nada que é bastante o que eu preciso. Há todos os tipos de problemas de segurança com o Silverlight interagir com serviços WCF que significam muitos exemplos potenciais simplesmente não funcionam. Tenho essencialmente sem tempo neste projeto e precisa de ajuda rápida. Alguém tem alguma sugestão de um exemplo simples adequado que ilustra como fazer isso? Eu sou um desenvolvedor experiente, mas tive que me ensinar serviços Silverlight e WCF e não há ninguém na minha área que sabe alguma coisa sobre estes. Mesmo tho' Eu fiz uma quantidade justa de trabalho ASP.NET Eu não sou um web / Javascript guru. Obrigado.

Foi útil?

Solução

Notificação push é suportado no Silverlight 2 usando o novo suporte WCF PollingDuplexHttpBinding. Há dois conjuntos instalados com o SDK Silverlight ( um para Silverlight um app para WCF servidor ).

Eu tenho um href="http://petermcg.wordpress.com/2008/11/19/silverlight-polling-duplex-part-4-wpf-client/" poucos blogue mensagens e um completo exemplo de aplicativo que demonstram como atualizações 'push' imagens de um servidor de aplicação de consola que a auto-anfitriões um serviço WCF para clientes conectados. Ele também mostra como cada cliente pode adicionar notas contra um estoque e têm essas notas sincronizado (empurrado do servidor) para todos os outros clientes conectados.

A versão mais recente da amostra (Parte 4) mostra como sincronizar atualizações empurrados entre ambos os clientes Silverlight e WPF usando dois pontos finais de servidor da seguinte forma:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace StockServer
{
    public class StockServiceHost : ServiceHost
    {
        public StockServiceHost(object singletonInstance, params Uri[] baseAddresses)
            : base(singletonInstance, baseAddresses)
        {
        }

        public StockServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }

        protected override void InitializeRuntime()
        {
            this.AddServiceEndpoint(
                typeof(IPolicyProvider),
                new WebHttpBinding(),
                new Uri("http://localhost:10201/")).Behaviors.Add(new WebHttpBehavior());

            this.AddServiceEndpoint(
                typeof(IStockService),
                new PollingDuplexHttpBinding(),
                new Uri("http://localhost:10201/SilverlightStockService"));

            this.AddServiceEndpoint(
                typeof(IStockService),
                new WSDualHttpBinding(WSDualHttpSecurityMode.None),
                new Uri("http://localhost:10201/WpfStockService"));

            base.InitializeRuntime();
        }
    }
}

clientes WPF conectar ao ponto de extremidade WSDualHttpBinding e clientes do Silverlight se conectar ao ponto de extremidade PollingDuplexHttpBinding do mesmo serviço WCF. O aplicativo também mostra como lidar com os requisitos da política de acesso do cliente Silverlight.

Clientes (Silverlight ou WPF) pode adicionar notas contra uma Estoque em sua interface e estas notas propagar de volta para o servidor a ser empurrado para todos os outros clientes. Isso demonstra a comunicação em qualquer direção e espero que executa toda a comunicação necessária exigida para a sua aplicação.

Você pode ver uma imagem do demonstração aplicativo em execução aqui .

Outras dicas

Não que estou empurrando Flex na moda fã menino, mas questão de naturalidade este é o tipo de arquitetura que construir em todas as aplicações de nossos baseados em Flex rotineiramente. Aqui é o que fazemos no Flex - Sem dúvida que poderia ser adequadamente traduzida para o Silverlight:

Tomamos três ingredientes e integrá-los juntos para realizar esta capacidade:

  1. padrão Comet (uma maneira compatível HTTP para fazer notificações push servidor - olhar no Wikipedia para mais informações)
  2. JMS de mensagens tópicos (publish / filas do assinante)
  3. Os BlazeDS Adobe servlet

O item últimos implementa o padrão Comet, suportes AMF empacotamento objeto (formato de serialização binária da Adobe para ActionScript3 objetos), e as pontes para uma fila ou tópico JMS. Quando ponte para um tópico, em seguida, vários clientes Flex execução em um navegador pode ser aproximada em que os assinantes para um tópico JMS. Assim, se qualquer cliente publica uma mensagem (ou o código do lado do servidor publica no tópico), todos os assinantes cliente terá a mensagem enviada a eles através de BlazeDS ea implementação padrão Comet.

Efetivamente você precisa localizar ou escrever um componente que realiza o que BlazeDS faz. Você também pode precisar de implementar um código de cliente que interage com o padrão Comet deste componente do lado do servidor.

O WCF suportar o padrão Comet e mensagens bidirecional? Especialmente onde está em conformidade com HTTP e a porta 80 ou 443 para SSL. Parece que você já olhou para isso e não encontrei nada para mensagens bidirecional. Então você pode precisar rolar as mangas e fazer alguma codificação.

Algumas coisas a notar sobre que faz o push do servidor para uma aplicação web:

BlazeDS suporta dois modos principais de implementar o padrão Comet (há realmente uma 3ª opção de sondagem, mas estou ignorando-o):

  1. longa-polling
  2. HTTP streaming de

A única longa-polling você deve encontrar-se mais universalmente suportável para a maioria dos navegadores web. Então você pode agilizar a apenas apoio que inicialmente. Ou você poderia gastar o tempo para fazer a sua tentativa de código do cliente HTTP streaming de primeira e interruptor para longa-polling, se necessário.

Como para um corretor de mensagem que pode fornecer publicar / capatibility Subscrevam, você pode considerar o uso ActiveMQ JMS. É código aberto e livre com o apoio da comunidade ativa (você pode comprar apoio também). Além disso, você pode usar NMS para integrar como um cliente .NET.

Ter um corretor de mensagens sentado no meio-tier é realmente importante porque vai ser um lugar para mensagens para ser colocado com segurança. Se seus clientes estão fazendo longa sondagem, você não quer que eles se perca qualquer mensagem nova, durante um intervalo quando eles não estão realmente conectado.

Outra coisa a considerar em cenários de alto volume de tráfego (centenas ou milhares de clientes, tais como um web site na Internet), você precisa ter uma abordagem para o padrão Comet que é escalável.

No mundo Flex / Java, o servlet BlazeDS (que é open source) foi modificado para trabalhar com modelo assíncrono. Em Java um ouvinte soquete pode ser construído para usar canais NIO e pools de threads Java Concurrency executor. O servidor web Tomcat tem um ouvinte NIO e suporte para eventos assíncronos Servlet 3.0. BlazeDS, em particular, foi modificado, embora, para trabalhar com o servidor web Jetty. A linha inferior é que a escalabilidade desta abordagem assíncrona significa um único servidor web física pode ser melhorada para suportar até cerca de 20.000 ligações de clientes Comet estilo simultâneos.

Tem sido um tempo desde que eu fiz sério de programação .NET, mas usado para as capacidades de io eram muito parecidas com Java 1.1, exceto com uma capacidade de manipulador de resultados assíncrona. Este, porém, não é a mesma coisa que criar ouvintes de soquete assíncronas através de canais de Java NIO. A implementação do canal NIO pode suportar centenas de milhares de conexões de soquete com um relativamente pequeno pool de threads. Mas C # e .NET passou por two ou três rotações significativas -. novas capacidades io talvez haja foram adicionadas que são comparáveis ??aos canais NIO

Eu só queria esclarecer que a PollingDuplexHttpBinding não implementar 'verdadeiras' notificações push, como revela o seu nome (polling). Do MSDN documentação :

Quando configurado com essa ligação, o cliente Silverlight periodicamente o serviço na camada de rede, e verifica se há novas mensagens que o serviço quer enviar no canal de retorno de chamada. As filas de serviços todas as mensagens enviadas no canal de retorno de chamada do cliente e entrega-los para o cliente quando as pesquisas de clientes do serviço.

No entanto, é mais eficiente do que a forma tradicional de polling um serviço web, uma vez que após cada votação, o servidor irá manter o canal aberto para um determinado período de tempo (digamos 1 minuto), e se chega uma mensagem nesse tempo ele vai diretamente 'push' a mensagem para o cliente. O cliente tem de renovar constantemente sua conexão, é por assim dizer urnas o serviço.

Se você quiser implementar notificações push real com o Silverlight Eu acredito que você precisa para trabalhar com tomadas, e eu recomendo a leitura de alguns dos posts de Dan Wahlin sobre o assunto.

Como alternativa,

Se você quer uma API Silverlight nativa sem proxies, pontes ou servidores web envolvida você poderia usar Nirvana dos meus-Canais como o seu middleware de mensagens. Confira Nirvana dos meus-Canais e seu site vitrine. (Desculpe eu sou um novo usuário e não pode enviar links):

Alex

EDIT: É bom realmente trabalhando. I got seriamente danificada mordido pelo "variáveis ??ocultas" em um fechamento: (

Eu usei o PollingDuplex para SL2 e eu acho que ele não está pronto para a produção ainda.

A minha questão principal é o fato de que ele não discrimina com os clientes na mesma máquina. Se eu executar 2 clientes, em seguida, um deles não será capaz de consultar o servidor mais e vai morrer de timeout. Há uma SessionId que é diferente para os 2 clientes mas é simplesmente ignorada no lado do cliente.

Da mesma forma, se eu matar um cliente e, em seguida, criar um novo mais tarde, em seguida, o novo cliente receberá as atualizações empurrar a partir do cliente anterior por um tempo.

Será que alguém encontrar os mesmos problemas ou eles são fixos no SL3?

Na verdade eu corri mais alguns códigos de demonstração e percebeu que, por algum motivo você tem que especificar o InstanceContextMode e InstanceMode para que o serviço é baseada em sessão e não um Singleton (tanto quanto eu posso dizer). Existem problemas de desempenho claros no código de demonstração simples que eu puxado.

É bastante lamentável que este comportamento não foi documentada.

A minha organização encontrou a implementação 2.0 / push WCF Silverlight ser um pouco "não está pronto para o horário nobre", pelo menos para o que estávamos planejando usá-lo.

Acabamos indo com XMPP / Jabber, porque é um animal mais bem formados, e você pode implementá-lo com bastante facilidade em Silverlight, por apenas recebendo alguns recursos fora da internet.

Eu acredito que o Silverlight 3.0 vai implementar uma implementação mais recente / mais bem formado impulso, pelo que eu posso dizer a partir de informações publicamente disponíveis.

O PollingDuplexHttpBinding é provavelmente a maneira mais elegante para fazê-lo.

Um possilby alternativa menos envolvidos é usar um soquete TCP do seu cliente Silverlight. Sempre que uma das necessidades dos clientes do Silverlight para ter uma atualização empurrado você pode enviar-lhe uma mensagem TCP que contém o nome do serviço WCF que precisa chamar ou alguma outra peça leve de informações.

Eu uso essa abordagem para um aplicativo e ele funciona bem.

Uma solução muito mais simples e mais poderoso no local http: //www.udaparts .com / document / Tutorial / slpush.htm

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