C#如何强制等待连接到 WCF 服务

Posted

技术标签:

【中文标题】C#如何强制等待连接到 WCF 服务【英文标题】:C# How to force the wait for the connection to a WCF service 【发布时间】:2018-06-01 00:53:58 【问题描述】:

我有一个作为本地 SYSTEM 运行的服务,它使用用户凭据启动另一个应用程序。 第二个应用程序只是一个托盘图标,它使用回调方法接收到的字符串向用户显示气球提示。第二个应用程序以双工模式连接到 WCF。

我的问题是,由于某种原因,与 WCF 的连接在 Main 方法结束时完成。所以我不能在执行后立即向应用程序发送回调消息,包含在最后一行“kiosk.MyStart(args);”中。回调仍然指向 null。

知道如何解决这个问题吗?

static void Main(string []args)

    if (Environment.UserInteractive)
    
         // Start the WCf service
         var host = new ServiceHost(typeof(WcfService));
         host.Open();

         //Launch the Kiosk Agent which connects to the WCF
         bool ret = ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");
         WinService kiosk = new WinService(args);
         // some checks and a welcome message is sent to the user.
         kiosk.MyStart(args);

         //...
         //...
    

编辑:再澄清一点,在 kiosk.MyStart 方法内部,我尝试执行回调以显示欢迎消息,但回调仍然为 NULL。 结果,我假设客户端由于任何原因没有正确启动,我再次启动它......

            if (WcfService.Callback != null)
                WcfService.Callback.UIMessageOnCallback(UIMessage);
            else
                ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");

【问题讨论】:

我不明白你在问什么,也不明白 WCF 在哪里涉及到 kiosk.MyStart 方法。你显示的代码是什么?那是服务吗?从哪里得到什么东西是空的?那么什么是 null 呢? args 还是 kiosk?这真的需要minimal reproducible example。 依靠 Windows 服务成功启动 GUI 应用程序是个坏主意。如果没有用户登录怎么办?也许考虑具有仅在登录时运行限制的 Windows 任务管理器? @rene,当我尝试调用回调时,我在 Kiosk.mystart 方法中得到了它。请参阅我在帖子中添加的注释。 @MickyD 你是对的,这就是为什么我还实施了检查是否有用户登录。如果没有用户登录,我不会尝试查找托盘图标进程向其发送任何消息。 @jacortijo 启动客户端应用程序您也可以使用所有用户的启动文件夹%programdata%\Microsoft\Windows\Start Menu\Programs\Startup在此文件夹中添加 kioskAgent 的快捷方式create-shortcut-on-desktop-c-sharp 【参考方案1】:

在回调方法上添加一个 try catch 块,如果客户端无法访问它,则可以取消订阅它。向您的客户发送一条 keepalive 消息以检查它是否可用也是一种很好的做法。

private void InformClient(ClientInfo clientInfo)

    var subscribers = this._subscriberRepository.GetAll();
    foreach (var subscriber in subscribers)
    
        try
        
            if (subscriber.Callback.FireInformClient(clientInfo));
            
                //If subscriber not reachable, unsubscribe it
                this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            
        
        catch (Exception exception)
        
            //If subscriber not reachable, unsubscribe it
            this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            Log.Error(nameof(InformClient), exception);
        
    

IClientCallback

public interface IClientCallback

    [OperationContract]
    bool FireInformClient(ClientInfo clientInfo);

如果您有更多订阅者,例如一个终端,服务器创建一个订阅者存储库来管理所有订阅者。

var callback = OperationContext.Current.GetCallbackChannel<IClientCallback>();
if (this._subscriberRepository.Subscribe(clientId, callback))

    return true;

【讨论】:

以上是关于C#如何强制等待连接到 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

WCF如何创建连接到同一个服务实例的两个通道

如何在 IIS 中正确托管连接到 SQLServer 的 WCF 数据服务?为啥我会收到错误消息?

如何使用 clientCredentialType="Basic" 将 Java 客户端连接到 WCF 服务

动态 WCF 客户端不会等待超过一分钟

WCF 连接到 Websocket 服务器

如何强制 Django 使用服务名称连接到 Oracle