gpt4 book ai didi

silverlight - 将 WCF 双工轮询与 Silverlight 结合使用时出现死锁

转载 作者:行者123 更新时间:2023-12-02 21:51:47 25 4
gpt4 key购买 nike

我按照 Tomek Janczuk 在 silverlight tv 上的演示创建了一个使用 WCF 双工轮询 Web 服务的聊天程序。客户端订阅服务器,然后服务器向所有连接的客户端发起通知,发布事件。

想法很简单,在客户端上,有一个允许客户端连接的按钮。一个文本框,客户端可以在其中编写消息并发布它,还有一个更大的文本框,用于显示从服务器收到的所有通知。

我连接了 3 个客户端(在不同的浏览器中 - IE、Firefox 和 Chrome),一切运行良好。他们顺利地发送和接收消息。当我关闭其中一个浏览器时,问题就开始了。一旦一个客户退出,其他客户就会陷入困境。他们不再收到通知。

我猜测服务器中遍历所有客户端并向它们发送通知的循环被卡在现在丢失的客户端上。我 try catch 异常并将其从客户端列表中删除(请参阅代码),但它仍然没有帮助。

有什么想法吗?

服务端代码如下:

    using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Runtime.Remoting.Channels;

namespace ChatDemo.Web
{
[ServiceContract]
public interface IChatNotification
{
// this will be used as a callback method, therefore it must be one way
[OperationContract(IsOneWay=true)]
void Notify(string message);

[OperationContract(IsOneWay = true)]
void Subscribed();
}

// define this as a callback contract - to allow push
[ServiceContract(Namespace="", CallbackContract=typeof(IChatNotification))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class ChatService
{
SynchronizedCollection<IChatNotification> clients = new SynchronizedCollection<IChatNotification>();

[OperationContract(IsOneWay=true)]
public void Subscribe()
{
IChatNotification cli = OperationContext.Current.GetCallbackChannel<IChatNotification>();
this.clients.Add(cli);
// inform the client it is now subscribed
cli.Subscribed();

Publish("New Client Connected: " + cli.GetHashCode());

}

[OperationContract(IsOneWay = true)]
public void Publish(string message)
{
SynchronizedCollection<IChatNotification> toRemove = new SynchronizedCollection<IChatNotification>();

foreach (IChatNotification channel in this.clients)
{
try
{
channel.Notify(message);
}
catch
{
toRemove.Add(channel);
}
}

// now remove all the dead channels
foreach (IChatNotification chnl in toRemove)
{
this.clients.Remove(chnl);
}
}
}
}

客户端代码如下:

void client_NotifyReceived(object sender, ChatServiceProxy.NotifyReceivedEventArgs e)
{
this.Messages.Text += string.Format("{0}\n\n", e.Error != null ? e.Error.ToString() : e.message);
}

private void MyMessage_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
this.client.PublishAsync(this.MyMessage.Text);
this.MyMessage.Text = "";
}
}

private void Button_Click(object sender, RoutedEventArgs e)
{
this.client = new ChatServiceProxy.ChatServiceClient(new PollingDuplexHttpBinding { DuplexMode = PollingDuplexMode.MultipleMessagesPerPoll }, new EndpointAddress("../ChatService.svc"));

// listen for server events
this.client.NotifyReceived += new EventHandler<ChatServiceProxy.NotifyReceivedEventArgs>(client_NotifyReceived);

this.client.SubscribedReceived += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_SubscribedReceived);

// subscribe for the server events
this.client.SubscribeAsync();

}

void client_SubscribedReceived(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
try
{
Messages.Text += "Connected!\n\n";
gsConnect.Color = Colors.Green;
}
catch
{
Messages.Text += "Failed to Connect!\n\n";

}
}

网络配置如下:

  <system.serviceModel>
<extensions>
<bindingExtensions>
<add name="pollingDuplex" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement, System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<pollingDuplex>
<binding name="myPollingDuplex" duplexMode="MultipleMessagesPerPoll"/>
</pollingDuplex>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service name="ChatDemo.Web.ChatService">
<endpoint address="" binding="pollingDuplex" bindingConfiguration="myPollingDuplex" contract="ChatDemo.Web.ChatService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>

最佳答案

尝试设置inactivityTimeout。以前也有同样的问题。对我来说很有效。pollingDuplex inactivityTimeout="02:00:00" serverPollTimeout="00:05:00"maxPendingMessagesPerSession="2147483647"maxPendingSessions="2147483647"duplexMode="SingleMessagePerPoll"

关于silverlight - 将 WCF 双工轮询与 Silverlight 结合使用时出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4647852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com