首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF服务之间的通信

WCF服务之间的通信
EN

Stack Overflow用户
提问于 2013-04-17 14:29:39
回答 1查看 1.3K关注 0票数 2

我正在将一个服务构建到一个现有的应用程序中,在这个应用程序中,构建每个服务的目的是只由一个客户端使用它,并且客户端和服务器是使用双工通信通道来设置的。

局限性

  1. 我没有办法重新设计现有的基础设施。
  2. 我不能使用可共享的会话

要求:

  1. 我需要能够在客户端服务之间进行通信(例如,如果用户单击某一项并希望共享该项,客户端可能由于任何原因而无法处理“共享”功能,并需要将其传递给另一个客户端处理--这必须通过服务来完成)
  2. 客户之间的沟通必须由服务进行。

为了开始工作,我在两个客户端之间直接设置了一个IPC通道(netNamedPipeBinding),但是我被告知要通过服务器发送所有东西。这个场景中的“服务器”,在大多数情况下,运行在与客户端相同的机器上,所以我想出了这个概念尝试的粗略证据(参见下面的代码块)。

问题:当为订阅服务调用方法时,当前服务的操作上下文(在其中调用方法)为空--这将使服务无法调用客户端。

我正在考虑使用他在ServiceModelEx框架中提供的Juval L wy的发布/订阅框架,但是当所有的客户已经在他们自己和他们各自的服务之间建立了双工通信设置时,似乎没有必要.因此,其意图只是添加一个简单的发布/订阅层,该层在概念上“位于”这些服务的“下面”,可以与任何愿意订阅的服务进行对话。

欢迎有建设性的意见和批评!

代码语言:javascript
复制
    public static class SubscriptionManager<TEventArgs> 
    where TEventArgs : class
{
    private static ConcurrentDictionary<int, Action<TEventArgs>> _subscribers =
       new ConcurrentDictionary<int, Action<TEventArgs>>();

    // sessionId is NOT the WCF SessionId
    public static void FireEvent( int sessionId, TEventArgs eventArgs ) 
    {
        var subscribers = _subscribers.Where( s => s.Key == sessionId );
        var actions = subscribers.Select( keyValuePair => keyValuePair.Value );

        foreach ( var action in actions )
            action.BeginInvoke( eventArgs, action.EndInvoke, null );
    }

    public static void Subscribe(int sessionId, Action<TEventArgs> eventHandler)
    {
        _subscribers.TryAdd(sessionId, eventHandler);
    }

    public static Action<TEventArgs> Unsubscribe(int sessionId)
    {
        Action<TEventArgs> eventHandler;
        _subscribers.TryRemove(sessionId, out eventHandler);
        return eventHandler;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-15 17:56:40

因此,首先,我正在实现的模式似乎可以被归类为一个中介模式

因此,我通过传递FireEvent调用服务的当前实例上下文来解决这个问题,在我的例子中,这个上下文应该与订阅服务的上下文相同。

我在这里处理的情况是在同一个用户和来自同一客户端计算机的上下文中操作的断开连接的客户端应用程序,但是(根据要求)它们必须通过服务层进行通信。

我开始从他的ThreadPoolBehavior库中使用WCF同步上下文和Juval的ServiceModelEx类,但是我被绑定到了一个实现中,Ninject扩展阻碍了它的实现。

因此,这个解决方案必须基于您自己的实现进行调整,但是为了让您了解我是如何让它工作的,下面是我更新的FireEvent方法的要点:

代码语言:javascript
复制
public static void FireEvent( int sessionId, TData eventData, InstanceContext context )
{
    var subscribers = Subscribers.Where( s => s.Key == sessionId );

    var eventArguments = subscribers.Select( kvp => kvp.Value );

    foreach ( var argument in eventArguments )
    {
        // set data associated with the event
        argument.SetData( eventData );

        NinjectInstanceProvider instanceProvider = null;
        Object instance = null;

        try
        {
            // get a "synchronized instance" of the service of type defined by event args
            instanceProvider = new NinjectInstanceProvider( argument.ServiceType );
            instance = instanceProvider.GetInstance( context );

            // get the method from our "synchronized instance"
            // filter by argument types so we don't run into any issues with ambiguity
            var argumentTypes = new[] { typeof ( TEventArgs ) };
            var method = instance.GetType().GetMethod( argument.Callback, argumentTypes );

            // our method arguments
            var arguments = new object[] { argument };

            // invoke the method on our "synchronized instance"
            method.Invoke( instance, arguments );

            // release the instance
            instanceProvider.ReleaseInstance( context, instance );
        }
        catch
        {
            // log
        }
        finally
        {
            if( provider != null )
            {
                if( instance != null ) { instanceProvider.ReleaseInstance( context, instance ); }
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16062786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档