.NETでWCFと名前付きパイプで双方向プロセス間通信を行う方法

この記事は公開から3年以上経過しています。

.NET開発でWCFと名前付きパイプ(サービス構成ファイル未使用)を使って双方向のプロセス間通信によるテキストメッセージの送受信を行う方法の最小構成のコンソールアプリケーション例です。

本例ではVB.NET(Framework 4.5.2)ですが、基本的にはC#の場合も同様です。

サンプルソースコード(VB.NET)

ホスト(サーバー)プログラム(Host.exe)
Host/HostProgram.vb

Imports System.ServiceModel
Imports Common

Module HostProgram

    Sub Main()

        ' 応答受信デリゲートを登録
        HostClass.Instance.OnReceived =
            Sub(msg)
                Console.WriteLine(msg)
            End Sub

        ' WCFサービス作成
        Dim binding = New NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
        Dim sh = New ServiceHost(HostClass.Instance)
        sh.AddServiceEndpoint(GetType(IHost), binding, ServiceEndPointAddress)
        sh.Open()

        Do
            ' コンソールで入力した応答メッセージをクライアントに送信
            Dim msg = Console.ReadLine()
            Try
                HostClass.Instance.Callback.Response(msg)
            Catch ex As Exception
                Console.WriteLine(ex.Message)
            End Try
        Loop

    End Sub

End Module

' Client→Host通信クラス(シングルトン)
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.Single)>
Public Class HostClass
    Implements IHost

    Private Shared ReadOnly _instance As Lazy(Of HostClass) = New Lazy(Of HostClass)(Function() New HostClass())

    Private _callback As ICallback

    ' コンストラクタ(private)
    Private Sub New()
    End Sub

    ' 自インスタンス
    Public Shared ReadOnly Property Instance As HostClass
        Get
            Return _instance.Value
        End Get
    End Property

    ' コールバック
    Public ReadOnly Property Callback As ICallback
        Get
            Return _callback
        End Get
    End Property

    ' 応答受信デリゲート
    Public Property OnReceived As Action(Of String)

    ' Hostへの要求
    Public Sub Request(msg As String) Implements IHost.Request

        ' 呼び出し元コールバックインターフェースを取得
        _callback = OperationContext.Current.GetCallbackChannel(Of ICallback)
        ' 応答受信デリゲート呼び出し
        OnReceived.Invoke(msg)

    End Sub

End Class

共通ライブラリ(Common.dll)
Common/WCFCommon.vb

Imports System.ServiceModel

Public Module Constants
    ' サービスエンドポイントアドレス(通信で使用する一意なパイプ名 ※GUIDはランダム)
    Public Const ServiceEndPointAddress = "net.pipe://localhost/D9AC0C87-ADA1-4F9A-B90B-DD8D1D954F18"
End Module

' Hostインターフェース
<ServiceContract(CallbackContract:=GetType(ICallback))>
Public Interface IHost

    ' 要求操作
    <OperationContract(IsOneWay:=True)>
    Sub Request(msg As String)

End Interface

' コールバックインターフェース
<ServiceContract>
Public Interface ICallback

    ' 応答操作
    <OperationContract(IsOneWay:=True)>
    Sub Response(msg As String)

End Interface

クライアントプログラム(Client.exe)
Client/ClientProgram.vb

Imports System.ServiceModel
Imports Common

Module ClientProgram

    Sub Main()

        Dim callback = New CallbackClass()
        ' 要求受信デリゲートを登録
        callback.OnReceived =
        Sub(msg)
            Console.WriteLine(msg)
        End Sub

        ' WCFクライアント双方向チャネル作成
        Dim binding = New NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
        Dim host = DuplexChannelFactory(Of IHost).CreateChannel(
                callback, binding, New EndpointAddress(ServiceEndPointAddress))

        Do
            ' コンソールで入力した要求メッセージをホストへ送信
            Dim msg = Console.ReadLine()
            Try
                host.Request(msg)
            Catch ex As Exception
                Console.WriteLine(ex.Message)
            End Try
        Loop

    End Sub

End Module

' Host→Client通信クラス
Public Class CallbackClass
    Implements ICallback

    ' 要求受信デリゲート
    Public OnReceived As Action(Of String)

    ' Clientへの応答
    Public Sub Response(msg As String) Implements ICallback.Response
        ' デリゲート呼び出し
        OnReceived.Invoke(msg)
    End Sub

End Class

動作イメージ

Hostプログラム→Clientプログラムの順にプログラムを起動します。
Client側でメッセージを入力してEnterを押下すると、Client側に入力したメッセージがHost側に表示され、続いてHost側でメッセージを入力してEnterを押下すると、Host側に入力したメッセージがClientに表示されます。

ちなみに実際のプログラムでWCFを利用する場合は、サービス操作がワーカースレッド上で非同期実行されること、IDisposableオブジェクトの破棄が必要なことにも注意が必要です。

参考ウェブサイトなど

以上です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする