teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

誤字の修正

2021/04/10 06:12

投稿

Mashimasa
Mashimasa

スコア51

title CHANGED
File without changes
body CHANGED
@@ -7,8 +7,8 @@
7
7
  またはもっと良い方法があれば教えて欲しいです。
8
8
 
9
9
  ### 該当のソースコード
10
- 私が作成したサンプルではホスト画面(ServerWindow.xaml)のボタンを押したタイミングでクライアントのコールバックメソッドを実行するような動作をします。
10
+ 私が作成したサンプルではホスト画面(ServerWindow.xaml)のボタンを押したタイミングでクライアントのコールバックメソッドを実行しています。
11
- ・クライアント接続時にホストのInitializeメソッドを実行し、ホスト側でOperationContextを保持するようにしています。
11
+
12
12
  ・クライアント画面でボタンを押した時は、クライアントのコンソールに"FromClient"と出力されます。
13
13
  ・ホスト画面でボタンを押した時は、クライアントのコンソールに"FromServer"と出力されます。
14
14
 

1

前回と質問の趣旨が変わった為内容変更しました。

2021/04/10 06:12

投稿

Mashimasa
Mashimasa

スコア51

title CHANGED
@@ -1,1 +1,1 @@
1
- WCFでのN:Nの通信
1
+ WCFでホスト側からクライアントメソッドを実行する方法について
body CHANGED
@@ -1,13 +1,170 @@
1
+ ### 実現したいこと
1
- 現在WCFでクライアントPC-サービス間で業務上通信をしるシステムがあります。
2
+ WCFでホスト側から任意のタイミングでクライアントのメソッド実行
2
3
 
4
+ ### 発生している問題
3
- クライアントは複数存在が可能ですが、ホストは1台です(N:1通信)。
5
+ クライアントのOperationContextをホスト保持ることで、実現することはできたですが
6
+ 果たしてこの方法は安全かどうかが疑問です。
4
- 通信を始めるの必ずクライアントで、クライアントの要求に対してサービス通知を返すような仕組みです。
7
+ またもっと良い方法あれば教えて欲しいです。
5
8
 
9
+ ### 該当のソースコード
10
+ ・私が作成したサンプルではホスト画面(ServerWindow.xaml)のボタンを押したタイミングでクライアントのコールバックメソッドを実行するような動作をします。
11
+ ・クライアント接続時にホストのInitializeメソッドを実行し、ホスト側でOperationContextを保持するようにしています。
12
+ ・クライアント画面でボタンを押した時は、クライアントのコンソールに"FromClient"と出力されます。
6
- これをホストを複数台(N:Nの通信)に通信を始めるのをクライアントからしたいいう要望がています。
13
+ ホスト画面でボタンた時は、クライアントのコンソール"FromServer"と出力されます。
7
14
 
8
- クライアント側でエンドポイントを複数保持し、サービスの通信先が切り替えが可能なのは調べて分かりましたが
9
- 複数のサービス側からの通知を受ける方法が分かりませんでした。
10
- (ちなみにサービス側は全て同じプログラムです。)
11
- そもそもWCFでこのようなことは実現可能なのでしょうか?
12
15
 
16
+
17
+ ####ホスト側
18
+ ServerWindow.xaml.vb
19
+ ```VBnet
20
+ Imports System.ComponentModel
21
+ Imports System.ServiceModel
22
+
23
+ Class ServerWindow
24
+ Private Host As ServiceHost
25
+ Public Shared Context As OperationContext
26
+
27
+ Private Sub ServerWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
28
+ Host = New ServiceHost(GetType(MyService))
29
+ Host.Open()
30
+ End Sub
31
+
32
+ Private Sub MainWindow_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
33
+ Host.Close()
34
+ End Sub
35
+
36
+ Private Sub ServerButton_Click(sender As Object, e As RoutedEventArgs) Handles ServerButton.Click
37
+ Dim callback = Context.GetCallbackChannel(Of IMyCallback)
38
+ callback.SendData("FromServer")
39
+ End Sub
40
+
41
+ End Class
42
+ ```
43
+ IMyService.vb
44
+ ```VBnet
45
+ Imports System.ServiceModel
46
+ <ServiceContract(CallbackContract:=GetType(IMyCallback))>
47
+ Public Interface IMyService
48
+ <OperationContract(IsOneWay:=True)>
49
+ Sub Initialize()
50
+
51
+ <OperationContract(IsOneWay:=True)>
52
+ Sub TestMethod()
53
+
54
+ End Interface
55
+
56
+ Public Interface IMyCallback
57
+ <OperationContract(IsOneWay:=True)>
58
+ Sub SendData(name As String)
59
+
60
+ End Interface
61
+ ```
62
+ MyService.vb
63
+ ```VBnet
64
+ Imports System.ServiceModel
65
+ <ServiceContract(CallbackContract:=GetType(IMyCallback))>
66
+ Public Interface IMyService
67
+ <OperationContract(IsOneWay:=True)>
68
+ Sub Initialize()
69
+
70
+ <OperationContract(IsOneWay:=True)>
71
+ Sub TestMethod()
72
+
73
+ End Interface
74
+
75
+ Public Interface IMyCallback
76
+ <OperationContract(IsOneWay:=True)>
77
+ Sub SendData(name As String)
78
+
79
+ End Interface
80
+ ```
81
+
82
+ app.config
83
+ ```xml
84
+ <system.serviceModel>
85
+ <bindings>
86
+ <netTcpBinding>
87
+ <binding name="NetTcpBinding_IMyService">
88
+ <security mode="None"/>
13
- 具体的には、複数のサービスが各クライアントに、ある条件に一致するクライアントPCが無いか、1台ずつ問い合わせをしたいです。
89
+ <readerQuotas maxArrayLength="1048576"/>
90
+ </binding>
91
+ </netTcpBinding>
92
+ </bindings>
93
+ <behaviors>
94
+ <serviceBehaviors>
95
+ <behavior name="MyServiceBehavior">
96
+ <serviceMetadata/>
97
+ </behavior>
98
+ </serviceBehaviors>
99
+ </behaviors>
100
+ <services>
101
+ <service name="WCFServer.MyService" behaviorConfiguration="MyServiceBehavior">
102
+ <host>
103
+ <baseAddresses>
104
+ <add baseAddress="net.tcp://0.0.0.0:48501/WCFTest"/>
105
+ </baseAddresses>
106
+ </host>
107
+ <endpoint address="net.tcp://0.0.0.0:48501/WCFTest" binding="netTcpBinding" contract="WCFServer.IMyService" bindingConfiguration="NetTcpBinding_IMyService"/>
108
+ <endpoint address="net.tcp://0.0.0.0:48501/mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
109
+ </service>
110
+ </services>
111
+ </system.serviceModel>
112
+ ```
113
+
114
+ ####クライアント側
115
+ ClientWindow.xaml.vb
116
+ ```VBNET
117
+
118
+ Imports System.ComponentModel
119
+ Imports System.ServiceModel
120
+ Imports WCFClient.WCFTest
121
+
122
+ Class ClientWindow : Implements WCFTest.IMyServiceCallback
123
+
124
+ Private Client As WCFTest.MyServiceClient
125
+
126
+ Private Sub ClientWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
127
+ Dim context = New InstanceContext(Me)
128
+ client = New WCFTest.MyServiceClient(context)
129
+ client.Initialize()
130
+ End Sub
131
+
132
+ Private Sub ClientWindow_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
133
+ Client.Close()
134
+ End Sub
135
+
136
+ Private Sub ClientButton_Click(sender As Object, e As RoutedEventArgs) Handles ClientButton.Click
137
+ client.TestMethod()
138
+ End Sub
139
+
140
+ Public Sub SendData(name As String) Implements IMyServiceCallback.SendData
141
+ Console.WriteLine(name)
142
+ End Sub
143
+
144
+ End Class
145
+
146
+ ```
147
+
148
+ app.config
149
+ ```xml
150
+ <system.serviceModel>
151
+ <bindings>
152
+ <netTcpBinding>
153
+ <binding name="NetTcpBinding_IMyService">
154
+ <security mode="None">
155
+ <transport sslProtocols="None" />
156
+ </security>
157
+ </binding>
158
+ </netTcpBinding>
159
+ </bindings>
160
+ <client>
161
+ <endpoint address="net.tcp://localhost:48501/WCFTest" binding="netTcpBinding"
162
+ bindingConfiguration="NetTcpBinding_IMyService" contract="WCFTest.IMyService"
163
+ name="NetTcpBinding_IMyService" />
164
+ </client>
165
+ </system.serviceModel>
166
+ ```
167
+
168
+
169
+ ### 補足情報(FW/ツールのバージョンなど)
170
+ WPF VB.net (.net 4.7.2)