WCF + Silverlight + Duplex

0

Problem jest taki. Mam najprostszy możliwy setup pollingDuplex (przez http), który można zobaczyć poniżej. Logowanie nowego użytkownika działa. Wylogowanie też.
Jedyną rzeczą którą nie działa jest SendMessage. Kiedy po stronie klienta wciska się przycisk, nic sie nie dzieje. W debuggerze można zobaczyć, że odpowiednia metoda nie jest w ogóle wywoływana..
Jest to problem od strony klienta bo kiedy w MainPage() dodaje SendMessageAsync() wraz z przyładową wiadomość, to następuje przekazanie do servera.

Kod service:

[ServiceContract(Namespace = "", CallbackContract=(typeof(IDuplexClient)))]
    //[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class NetGameService
    {
        private static SynchronizedCollection<IDuplexClient> _clients = new SynchronizedCollection<IDuplexClient>();
        
        [OperationContract]
        public void Login()
        {
            IDuplexClient client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
            lock (_clients)
            {
                _clients.Add(client);
            }
        }

        [OperationContract]
        public void Logout()
        {
            IDuplexClient client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
            lock (_clients)
            {
                _clients.Remove(client);
            }
        }

        [OperationContract]
        public void SendMessage(string message)
        {
            IDuplexClient client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();

            foreach (IDuplexClient item in _clients)
            {
                try
                {
                    item.DiplayMessage(message);
                }
                catch (Exception)
                {
                }
            }
        }
    }

    [ServiceContract]
    public interface IDuplexClient
    {
        [OperationContract(IsOneWay = true)]
        void DiplayMessage(string message);
    }
 

Kod klienta:

 
NetGameServiceClient _client;
        public MainPage()
        {
            InitializeComponent();
            _client = new NetGameServiceClient(new PollingDuplexHttpBinding {DuplexMode = PollingDuplexMode.MultipleMessagesPerPoll},
                new EndpointAddress("../NetGameService.svc"));
            _client.DiplayMessageReceived += new EventHandler<DiplayMessageReceivedEventArgs>(client_NotifyReceived);
            _client.LoginAsync();
        }

        private void client_NotifyReceived(object sender, DiplayMessageReceivedEventArgs e)
        {
            lstMessages.Items.Add(e.message);
        }

        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            if(btnLogin.Content.ToString() == "Login")
            {
                if(String.IsNullOrEmpty(txtUsername.Text))
                {
                    MessageBox.Show("Please Enter a username!", "Warring", MessageBoxButton.OK);
                }
                else
                {
                    _client.LoginAsync();
                    btnLogin.Content = "Logout";
                    txtUsername.IsEnabled = false;

                    txtMessage.IsEnabled = true;
                    btnSend.IsEnabled = true;
                }
            }
            else
            {
                _client.LogoutAsync();
                btnLogin.Content = "Login";
                txtUsername.Text = string.Empty;
                txtUsername.IsEnabled = true;

                txtMessage.IsEnabled = false;
                btnSend.IsEnabled = false;
            }
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            _client.SendMessageAsync(string.Format("{0} said: {1}", txtUsername.Text, txtMessage.Text));
            //_client.SendMessageAsync(txtMessage.Text);
            txtMessage.Text = string.Empty;
        }

        private void txtMessage_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                _client.SendMessageAsync(string.Format("{0} said: {1}", txtUsername.Text, txtMessage.Text));
            }

        }

    }
<Grid x:Name="LayoutRoot" Background="White" MaxHeight="300" MaxWidth="400">
        <Grid.RowDefinitions>
            <RowDefinition Height="10" />
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
            <RowDefinition Height="50" />
            <RowDefinition Height="10" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock Text="Username:" Margin="10,0,0,0" VerticalAlignment="Center" />
            <TextBox x:Name="txtUsername" Width="120" VerticalAlignment="Center" Margin="5,0,0,0" />
            <Button x:Name="btnLogin" Width="70" VerticalAlignment="Center" Margin="5,0,0,0" Height="21"
                    Content="Login" Click="btnLogin_Click" />
        </StackPanel>
        
        <ListBox x:Name="lstMessages" Grid.Row="2" Margin="10,5" />
        <Grid Grid.Row="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBox x:Name="txtMessage" Margin="10,0,5,0" KeyDown="txtMessage_KeyDown" />
            <Button Grid.Column="1" x:Name="btnSend" Content="Send" Width="80" Margin="0,0,10,0" Click="btnSend_Click" />
        </Grid>
    </Grid>
 
0

Sam sobie odpowiem.

otóż wygląda na to, ze Zarówno FireFox 4.0.1 IE9 Chrome (najnowsza beta), gryzą się, kiedy mamy włączoną obsługe MultipleMessagesPerPoll. Trzeba zmienić na SingleMessagePerPoll, niestety po takiej zmianie bardzo spada wydajność w przekazywaniu wiadomości.

Natrafiłem, na to wyjaśnienie zupełnym przypadkiem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1