質問編集履歴
5
title
CHANGED
File without changes
|
body
CHANGED
@@ -17,6 +17,10 @@
|
|
17
17
|
|
18
18
|
WCFによるプロセス間のイベント通知が出来ない。
|
19
19
|
|
20
|
+
下記のソースコードのようにすると、以下のようになってしまいます。
|
21
|
+
1. 1つ目のプロセスでイベント登録(OnCallback)。
|
22
|
+
2. 2つ目のプロセスでInvokeしようとすると、OnCallbackがnullになっていてInvokeされない。
|
23
|
+
|
20
24
|
### 該当のソースコード
|
21
25
|
|
22
26
|
サービスの定義(IdataTransferService.cs)
|
4
「前提・実現したいこと」に追記しました。
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,6 +7,10 @@
|
|
7
7
|
やりたいことのイメージとして、以下の画像を参考にして下さい。
|
8
8
|

|
9
9
|
|
10
|
+
ClientとServiceの双方向通信のサンプルはネット上にたくさん転がっていますが、
|
11
|
+
あるClientがイベントを叩くと、もう一方のClientにイベント通知がされる、
|
12
|
+
というパターンが見つかりませんでした。
|
13
|
+
|
10
14
|
参考としてサイトをご紹介頂ける場合は、英語のサイトでも構いません。
|
11
15
|
|
12
16
|
### 発生している問題・エラーメッセージ
|
3
イメージ画像を追加しました。
title
CHANGED
File without changes
|
body
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
プロセス間でイベント通知を行い、データを転送したいのですが、双方向通信にしてもイベントが飛びません。
|
6
6
|
WCFを利用したプロセス間のイベント通知によるデータ転送の実現方法を教えて頂きたいです。
|
7
|
+
やりたいことのイメージとして、以下の画像を参考にして下さい。
|
8
|
+

|
7
9
|
|
8
10
|
参考としてサイトをご紹介頂ける場合は、英語のサイトでも構いません。
|
9
11
|
|
2
コールバックインターフェースの実装方法を変更しました。
title
CHANGED
File without changes
|
body
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
WCFを使用して、名前付きパイプによるプロセス間通信を行うプログラムを実装しています。
|
4
4
|
|
5
5
|
プロセス間でイベント通知を行い、データを転送したいのですが、双方向通信にしてもイベントが飛びません。
|
6
|
-
|
7
6
|
WCFを利用したプロセス間のイベント通知によるデータ転送の実現方法を教えて頂きたいです。
|
8
|
-
英語のサイトでも構いません。
|
9
7
|
|
8
|
+
参考としてサイトをご紹介頂ける場合は、英語のサイトでも構いません。
|
9
|
+
|
10
10
|
### 発生している問題・エラーメッセージ
|
11
11
|
|
12
12
|
WCFによるプロセス間のイベント通知が出来ない。
|
@@ -17,22 +17,26 @@
|
|
17
17
|
```C#
|
18
18
|
namespace DataTransferWCFService
|
19
19
|
{
|
20
|
-
// メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コードと config ファイルの両方で同時にインターフェイス名 "IService1" を変更できます。
|
21
20
|
[ServiceContract(CallbackContract = typeof(IGetResponseCallback))]
|
22
21
|
public interface IDataTransferService
|
23
22
|
{
|
24
|
-
// TODO: ここにサービス操作を追加します。
|
25
|
-
|
26
23
|
[OperationContract(IsOneWay = true)]
|
27
24
|
void Register(byte[] data);
|
25
|
+
|
28
26
|
[OperationContract(IsOneWay = true)]
|
29
27
|
void Clear();
|
28
|
+
|
30
29
|
[OperationContract]
|
31
30
|
byte[] GetResponse(UInt32 id, byte[] request);
|
31
|
+
|
32
|
+
/// <summary>
|
33
|
+
/// コールバック用
|
34
|
+
/// </summary>
|
35
|
+
/// <param name="id"></param>
|
36
|
+
/// <param name="message"></param>
|
37
|
+
[OperationContract(IsOneWay = true)]
|
38
|
+
void Send(UInt32 id, byte[] message);
|
32
39
|
}
|
33
|
-
|
34
|
-
// サービス操作に複合型を追加するには、以下のサンプルに示すようにデータ コントラクトを使用します。
|
35
|
-
// プロジェクトに XSD ファイルを追加できます。プロジェクトのビルド後、そこで定義されたデータ型を、名前空間 "DataTransferWCFService.ContractType" で直接使用できます。
|
36
40
|
}
|
37
41
|
```
|
38
42
|
|
@@ -52,13 +56,10 @@
|
|
52
56
|
```C#
|
53
57
|
namespace DataTransferWCFService
|
54
58
|
{
|
55
|
-
// メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コードと config ファイルの両方で同時にクラス名 "Service1" を変更できます。
|
56
|
-
public class DataTransferService : IDataTransferService
|
59
|
+
public class DataTransferService : IDataTransferService
|
57
60
|
{
|
58
61
|
private static List<byte[]> dataList = new List<byte[]>();
|
59
|
-
|
62
|
+
|
60
|
-
public event CallbackEventHandler OnCallback;
|
61
|
-
|
62
63
|
public void Clear()
|
63
64
|
{
|
64
65
|
dataList.Clear();
|
@@ -66,24 +67,29 @@
|
|
66
67
|
|
67
68
|
public byte[] GetResponse(uint id, byte[] request)
|
68
69
|
{
|
69
|
-
|
70
|
+
|
70
71
|
byte[] response = dataList.ElementAt((int)id)
|
71
72
|
.Concat(request)
|
72
73
|
.ToArray();
|
73
74
|
|
74
|
-
callback.GetResponseCallback(id, response);
|
75
|
-
|
76
75
|
return response;
|
77
76
|
}
|
78
77
|
|
79
|
-
public void
|
78
|
+
public void Register(byte[] data)
|
80
79
|
{
|
81
|
-
|
80
|
+
dataList.Add(data);
|
82
81
|
}
|
83
82
|
|
83
|
+
/// <summary>
|
84
|
+
/// コールバック用
|
85
|
+
/// </summary>
|
86
|
+
/// <param name="id"></param>
|
87
|
+
/// <param name="request"></param>
|
84
|
-
public void
|
88
|
+
public void Send(uint id, byte[] message)
|
85
89
|
{
|
90
|
+
IGetResponseCallback callback = OperationContext.Current.GetCallbackChannel<IGetResponseCallback>();
|
91
|
+
|
86
|
-
|
92
|
+
callback.GetResponseCallback(id, message);
|
87
93
|
}
|
88
94
|
}
|
89
95
|
}
|
@@ -95,43 +101,72 @@
|
|
95
101
|
{
|
96
102
|
public class DataTransfer
|
97
103
|
{
|
98
|
-
public
|
104
|
+
public _DataTransfer instance = _DataTransfer.Instance;
|
105
|
+
|
106
|
+
/// <summary>
|
107
|
+
/// サービスの開始とチャンネルの実体化
|
108
|
+
/// </summary>
|
109
|
+
public void PreStart()
|
99
110
|
{
|
100
|
-
get
|
101
|
-
{
|
102
|
-
|
111
|
+
this.instance.Start();
|
103
|
-
|
112
|
+
this.instance.Create();
|
104
113
|
}
|
105
114
|
|
115
|
+
/// <summary>
|
116
|
+
/// チャンネルの実体化
|
117
|
+
/// </summary>
|
118
|
+
public void Create()
|
119
|
+
{
|
120
|
+
this.instance.Create();
|
121
|
+
}
|
122
|
+
|
106
123
|
public void Register(byte[] data)
|
107
124
|
{
|
108
|
-
|
125
|
+
this.instance.Register(data);
|
109
126
|
}
|
110
127
|
|
111
128
|
public void Clear()
|
112
129
|
{
|
113
|
-
|
130
|
+
this.instance.Clear();
|
114
131
|
}
|
115
132
|
|
116
133
|
public byte[] GetResponse(UInt32 id, byte[] request)
|
117
134
|
{
|
118
|
-
return
|
135
|
+
return this.instance.GetResponse(id, request);
|
119
136
|
}
|
120
137
|
}
|
121
138
|
|
122
|
-
|
139
|
+
public class _DataTransfer : IGetResponseCallback
|
123
140
|
{
|
124
|
-
private static string
|
141
|
+
private static string PIPE_NAME = @"net.pipe://sample";
|
125
|
-
|
142
|
+
public ServiceHost host;
|
126
|
-
|
143
|
+
public IDataTransferService proxy;
|
127
|
-
|
144
|
+
public DuplexChannelFactory<IDataTransferService> factory;
|
145
|
+
public delegate void CallbackEventHandler(object sender, CommunicationEventArgs args);
|
146
|
+
public event CallbackEventHandler OnCallback;
|
147
|
+
//シングルトンパターン
|
128
|
-
|
148
|
+
private static _DataTransfer instance = new _DataTransfer();
|
149
|
+
public static _DataTransfer Instance
|
150
|
+
{
|
151
|
+
get
|
152
|
+
{
|
153
|
+
return instance;
|
154
|
+
}
|
155
|
+
}
|
129
156
|
|
130
|
-
|
157
|
+
private _DataTransfer()
|
131
158
|
{
|
132
|
-
host = new ServiceHost(typeof(IDataTransferService), new Uri(pipeName));
|
133
159
|
|
160
|
+
}
|
161
|
+
|
162
|
+
/// <summary>
|
163
|
+
/// サービスを開始
|
164
|
+
/// </summary>
|
165
|
+
public void Start()
|
166
|
+
{
|
167
|
+
Instance.host = new ServiceHost(typeof(IDataTransferService), new Uri(PIPE_NAME));
|
168
|
+
|
134
|
-
host.AddServiceEndpoint(typeof(IDataTransferService), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
169
|
+
Instance.host.AddServiceEndpoint(typeof(IDataTransferService), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
135
170
|
{
|
136
171
|
ReceiveTimeout = TimeSpan.MaxValue
|
137
172
|
}, string.Empty);
|
@@ -140,29 +175,29 @@
|
|
140
175
|
{
|
141
176
|
host.Open();
|
142
177
|
}
|
143
|
-
catch(Exception ex)
|
178
|
+
catch (Exception ex)
|
144
179
|
{
|
145
180
|
Debug.WriteLine(ex.Message);
|
146
181
|
}
|
147
|
-
|
148
|
-
Create();
|
149
|
-
|
150
182
|
}
|
151
183
|
|
184
|
+
/// <summary>
|
185
|
+
/// チャンネルの実体化
|
186
|
+
/// </summary>
|
152
|
-
public
|
187
|
+
public void Create()
|
153
188
|
{
|
154
|
-
factory = new DuplexChannelFactory<IDataTransferService>(new InstanceContext(
|
189
|
+
Instance.factory = new DuplexChannelFactory<IDataTransferService>(new InstanceContext(Instance), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
155
190
|
{
|
156
191
|
MaxReceivedMessageSize = Int32.MaxValue
|
157
|
-
},
|
192
|
+
}, PIPE_NAME);
|
158
|
-
|
193
|
+
Instance.proxy = Instance.factory.CreateChannel();
|
159
194
|
}
|
160
195
|
|
161
|
-
public
|
196
|
+
public void Clear()
|
162
197
|
{
|
163
198
|
try
|
164
199
|
{
|
165
|
-
|
200
|
+
Instance.proxy.Clear();
|
166
201
|
}
|
167
202
|
catch(Exception ex)
|
168
203
|
{
|
@@ -170,11 +205,11 @@
|
|
170
205
|
}
|
171
206
|
}
|
172
207
|
|
173
|
-
public
|
208
|
+
public void Register(byte[] data)
|
174
209
|
{
|
175
210
|
try
|
176
211
|
{
|
177
|
-
|
212
|
+
Instance.proxy.Register(data);
|
178
213
|
}
|
179
214
|
catch(Exception ex)
|
180
215
|
{
|
@@ -182,11 +217,17 @@
|
|
182
217
|
}
|
183
218
|
}
|
184
219
|
|
185
|
-
public
|
220
|
+
public byte[] GetResponse(UInt32 id, byte[] request)
|
186
221
|
{
|
187
222
|
try
|
188
223
|
{
|
189
|
-
|
224
|
+
Instance.proxy.Send(id, request);
|
225
|
+
|
226
|
+
byte[] response = Instance.proxy.GetResponse(id, request);
|
227
|
+
|
228
|
+
Instance.proxy.Send(id, response);
|
229
|
+
|
230
|
+
return response;
|
190
231
|
}
|
191
232
|
catch(Exception ex)
|
192
233
|
{
|
@@ -195,58 +236,20 @@
|
|
195
236
|
return null;
|
196
237
|
}
|
197
238
|
}
|
239
|
+
|
240
|
+
/// <summary>
|
241
|
+
/// コールバックメソッドの実装
|
242
|
+
/// </summary>
|
243
|
+
/// <param name="id"></param>
|
244
|
+
/// <param name="message"></param>
|
245
|
+
public void GetResponseCallback(uint id, byte[] message)
|
246
|
+
{
|
247
|
+
Instance.OnCallback?.Invoke(this, new CommunicationEventArgs(id, message));
|
248
|
+
}
|
198
249
|
}
|
199
250
|
}
|
200
251
|
```
|
201
252
|
|
202
|
-
WCFの設定ファイル(App.config)
|
203
|
-
```XML
|
204
|
-
<?xml version="1.0" encoding="utf-8" ?>
|
205
|
-
<configuration>
|
206
|
-
|
207
|
-
<appSettings>
|
208
|
-
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
|
209
|
-
</appSettings>
|
210
|
-
<system.web>
|
211
|
-
<compilation debug="true" />
|
212
|
-
</system.web>
|
213
|
-
<!-- サービス ライブラリ プロジェクトの展開時に、構成ファイルの内容をホストの app.config ファイルに追加する
|
214
|
-
必要があります。System.Configuration は、ライブラリの構成ファイルをサポートしていません。 -->
|
215
|
-
<system.serviceModel>
|
216
|
-
<services>
|
217
|
-
<service name="DataTransferWCFService.DataTransferService">
|
218
|
-
<endpoint address="" binding="wsDualHttpBinding" contract="DataTransferWCFService.IDataTransferService">
|
219
|
-
<identity>
|
220
|
-
<dns value="localhost" />
|
221
|
-
</identity>
|
222
|
-
</endpoint>
|
223
|
-
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
|
224
|
-
<host>
|
225
|
-
<baseAddresses>
|
226
|
-
<add baseAddress="http://localhost:8733/Design_Time_Addresses/DataTransferWCFService/Service1/" />
|
227
|
-
</baseAddresses>
|
228
|
-
</host>
|
229
|
-
</service>
|
230
|
-
</services>
|
231
|
-
<behaviors>
|
232
|
-
<serviceBehaviors>
|
233
|
-
<behavior>
|
234
|
-
<!-- メタデータ情報の開示を避けるには、
|
235
|
-
展開する前に下の値を false に設定します -->
|
236
|
-
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
|
237
|
-
<!-- デバッグ目的で障害発生時の例外の詳細を受け取るには、
|
238
|
-
下の値を true に設定します。例外情報の開示を避けるには、
|
239
|
-
展開する前に false に設定します -->
|
240
|
-
<serviceDebug includeExceptionDetailInFaults="False" />
|
241
|
-
</behavior>
|
242
|
-
</serviceBehaviors>
|
243
|
-
</behaviors>
|
244
|
-
</system.serviceModel>
|
245
|
-
|
246
|
-
</configuration>
|
247
|
-
|
248
|
-
```
|
249
|
-
|
250
253
|
本体(Program.cs)
|
251
254
|
```C#
|
252
255
|
namespace WCFIPC
|
@@ -261,6 +264,7 @@
|
|
261
264
|
|
262
265
|
//2つ目のプロセスでは
|
263
266
|
DataTransfer.DataTransfer dataTransfer = new DataTransfer.DataTransfer();
|
267
|
+
dataTransfer.Create();
|
264
268
|
var response = dataTransfer.GetResponse(0xFF, new byte[] { 0x78, 0x90 });
|
265
269
|
}
|
266
270
|
}
|
@@ -271,13 +275,14 @@
|
|
271
275
|
|
272
276
|
public void Register(byte[] data)
|
273
277
|
{
|
278
|
+
this.service.PreStart();
|
274
279
|
this.service.Register(data);
|
275
|
-
|
280
|
+
|
276
|
-
//ここで
|
281
|
+
//ここでイベントの購読をしたい
|
277
|
-
this.service.
|
282
|
+
this.service.instance.OnCallback += Instance_OnCallback;
|
278
283
|
}
|
279
284
|
|
280
|
-
private void
|
285
|
+
private void Instance_OnCallback(object sender, DataTransferWCFService.CommunicationEventArgs args)
|
281
286
|
{
|
282
287
|
Console.Write(args.Message);
|
283
288
|
}
|
@@ -292,8 +297,24 @@
|
|
292
297
|
|
293
298
|
### 試したこと
|
294
299
|
|
300
|
+
・上記実装。
|
301
|
+
・以下のようにイベントを処理するクラスを実装し、DataTransferServiceでそのオブジェクトを保持した。サービスインターフェースにそのオブジェクトを返すようなメソッドを定義し実装したが、期待通りの動作をしてくれなかった。
|
295
|
-
|
302
|
+
```C#
|
303
|
+
[DataContract]
|
304
|
+
public class EventHelper
|
305
|
+
{
|
306
|
+
public delegate void CallbackEventHandler(object sender, CommunicationEventArgs args);
|
307
|
+
[field: DataMember]
|
308
|
+
public event CallbackEventHandler OnCallback;
|
296
309
|
|
310
|
+
[OperationContract]
|
311
|
+
public void Fire(UInt32 id, byte[] message)
|
312
|
+
{
|
313
|
+
this.OnCallback?.Invoke(this, new CommunicationEventArgs(id, message));
|
314
|
+
}
|
315
|
+
}
|
316
|
+
```
|
317
|
+
|
297
318
|
### 補足情報(FW/ツールのバージョンなど)
|
298
319
|
|
299
320
|
Visual Studio 2019
|
1
ソースコードを追加しました。
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,22 +7,294 @@
|
|
7
7
|
WCFを利用したプロセス間のイベント通知によるデータ転送の実現方法を教えて頂きたいです。
|
8
8
|
英語のサイトでも構いません。
|
9
9
|
|
10
|
-
漠然とした質問で申し訳ございません。
|
11
|
-
|
12
10
|
### 発生している問題・エラーメッセージ
|
13
11
|
|
14
12
|
WCFによるプロセス間のイベント通知が出来ない。
|
15
13
|
|
16
14
|
### 該当のソースコード
|
17
15
|
|
16
|
+
サービスの定義(IdataTransferService.cs)
|
18
17
|
```C#
|
18
|
+
namespace DataTransferWCFService
|
19
|
+
{
|
20
|
+
// メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コードと config ファイルの両方で同時にインターフェイス名 "IService1" を変更できます。
|
21
|
+
[ServiceContract(CallbackContract = typeof(IGetResponseCallback))]
|
22
|
+
public interface IDataTransferService
|
23
|
+
{
|
24
|
+
// TODO: ここにサービス操作を追加します。
|
25
|
+
|
26
|
+
[OperationContract(IsOneWay = true)]
|
27
|
+
void Register(byte[] data);
|
28
|
+
[OperationContract(IsOneWay = true)]
|
19
|
-
|
29
|
+
void Clear();
|
30
|
+
[OperationContract]
|
31
|
+
byte[] GetResponse(UInt32 id, byte[] request);
|
32
|
+
}
|
33
|
+
|
34
|
+
// サービス操作に複合型を追加するには、以下のサンプルに示すようにデータ コントラクトを使用します。
|
35
|
+
// プロジェクトに XSD ファイルを追加できます。プロジェクトのビルド後、そこで定義されたデータ型を、名前空間 "DataTransferWCFService.ContractType" で直接使用できます。
|
36
|
+
}
|
20
37
|
```
|
21
38
|
|
39
|
+
コールバックインターフェースの定義(IGetResponseCallback.cs)
|
40
|
+
```C#
|
41
|
+
namespace DataTransferWCFService
|
42
|
+
{
|
43
|
+
public interface IGetResponseCallback
|
44
|
+
{
|
45
|
+
[OperationContract(IsOneWay = true)]
|
46
|
+
void GetResponseCallback(UInt32 id, byte[] message);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
```
|
50
|
+
|
51
|
+
サービスの実装(DataTransferService.cs)
|
52
|
+
```C#
|
53
|
+
namespace DataTransferWCFService
|
54
|
+
{
|
55
|
+
// メモ: [リファクター] メニューの [名前の変更] コマンドを使用すると、コードと config ファイルの両方で同時にクラス名 "Service1" を変更できます。
|
56
|
+
public class DataTransferService : IDataTransferService, IGetResponseCallback
|
57
|
+
{
|
58
|
+
private static List<byte[]> dataList = new List<byte[]>();
|
59
|
+
public delegate void CallbackEventHandler(object sender, CommunicationEventArgs args);
|
60
|
+
public event CallbackEventHandler OnCallback;
|
61
|
+
|
62
|
+
public void Clear()
|
63
|
+
{
|
64
|
+
dataList.Clear();
|
65
|
+
}
|
66
|
+
|
67
|
+
public byte[] GetResponse(uint id, byte[] request)
|
68
|
+
{
|
69
|
+
IGetResponseCallback callback = OperationContext.Current.GetCallbackChannel<IGetResponseCallback>();
|
70
|
+
byte[] response = dataList.ElementAt((int)id)
|
71
|
+
.Concat(request)
|
72
|
+
.ToArray();
|
73
|
+
|
74
|
+
callback.GetResponseCallback(id, response);
|
75
|
+
|
76
|
+
return response;
|
77
|
+
}
|
78
|
+
|
79
|
+
public void GetResponseCallback(uint id, byte[] message)
|
80
|
+
{
|
81
|
+
this.OnCallback?.Invoke(this, new CommunicationEventArgs(id, message));
|
82
|
+
}
|
83
|
+
|
84
|
+
public void Register(byte[] data)
|
85
|
+
{
|
86
|
+
dataList.Add(data);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
```
|
91
|
+
|
92
|
+
サービスの開始周り(DataTransfer.cs)
|
93
|
+
```C#
|
94
|
+
namespace DataTransfer
|
95
|
+
{
|
96
|
+
public class DataTransfer
|
97
|
+
{
|
98
|
+
public DataTransferService DataTransferServiceInstance
|
99
|
+
{
|
100
|
+
get
|
101
|
+
{
|
102
|
+
return _DataTransfer.dtService;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
public void Register(byte[] data)
|
107
|
+
{
|
108
|
+
_DataTransfer.Register(data);
|
109
|
+
}
|
110
|
+
|
111
|
+
public void Clear()
|
112
|
+
{
|
113
|
+
_DataTransfer.Clear();
|
114
|
+
}
|
115
|
+
|
116
|
+
public byte[] GetResponse(UInt32 id, byte[] request)
|
117
|
+
{
|
118
|
+
return _DataTransfer.GetResponse(id, request);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
static class _DataTransfer
|
123
|
+
{
|
124
|
+
private static string pipeName = @"net.pipe://sample";
|
125
|
+
private static ServiceHost host;
|
126
|
+
private static IDataTransferService client;
|
127
|
+
static DuplexChannelFactory<IDataTransferService> factory;
|
128
|
+
public static DataTransferService dtService = new DataTransferService();
|
129
|
+
|
130
|
+
static _DataTransfer()
|
131
|
+
{
|
132
|
+
host = new ServiceHost(typeof(IDataTransferService), new Uri(pipeName));
|
133
|
+
|
134
|
+
host.AddServiceEndpoint(typeof(IDataTransferService), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
135
|
+
{
|
136
|
+
ReceiveTimeout = TimeSpan.MaxValue
|
137
|
+
}, string.Empty);
|
138
|
+
|
139
|
+
try
|
140
|
+
{
|
141
|
+
host.Open();
|
142
|
+
}
|
143
|
+
catch(Exception ex)
|
144
|
+
{
|
145
|
+
Debug.WriteLine(ex.Message);
|
146
|
+
}
|
147
|
+
|
148
|
+
Create();
|
149
|
+
|
150
|
+
}
|
151
|
+
|
152
|
+
public static void Create()
|
153
|
+
{
|
154
|
+
factory = new DuplexChannelFactory<IDataTransferService>(new InstanceContext(dtService), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
|
155
|
+
{
|
156
|
+
MaxReceivedMessageSize = Int32.MaxValue
|
157
|
+
}, pipeName);
|
158
|
+
client = factory.CreateChannel();
|
159
|
+
}
|
160
|
+
|
161
|
+
public static void Clear()
|
162
|
+
{
|
163
|
+
try
|
164
|
+
{
|
165
|
+
client.Clear();
|
166
|
+
}
|
167
|
+
catch(Exception ex)
|
168
|
+
{
|
169
|
+
Debug.WriteLine(ex.Message);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
public static void Register(byte[] data)
|
174
|
+
{
|
175
|
+
try
|
176
|
+
{
|
177
|
+
client.Register(data);
|
178
|
+
}
|
179
|
+
catch(Exception ex)
|
180
|
+
{
|
181
|
+
Debug.WriteLine(ex.Message);
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
public static byte[] GetResponse(UInt32 id, byte[] request)
|
186
|
+
{
|
187
|
+
try
|
188
|
+
{
|
189
|
+
return client.GetResponse(id, request);
|
190
|
+
}
|
191
|
+
catch(Exception ex)
|
192
|
+
{
|
193
|
+
Debug.WriteLine(ex.Message);
|
194
|
+
|
195
|
+
return null;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
```
|
201
|
+
|
202
|
+
WCFの設定ファイル(App.config)
|
203
|
+
```XML
|
204
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
205
|
+
<configuration>
|
206
|
+
|
207
|
+
<appSettings>
|
208
|
+
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
|
209
|
+
</appSettings>
|
210
|
+
<system.web>
|
211
|
+
<compilation debug="true" />
|
212
|
+
</system.web>
|
213
|
+
<!-- サービス ライブラリ プロジェクトの展開時に、構成ファイルの内容をホストの app.config ファイルに追加する
|
214
|
+
必要があります。System.Configuration は、ライブラリの構成ファイルをサポートしていません。 -->
|
215
|
+
<system.serviceModel>
|
216
|
+
<services>
|
217
|
+
<service name="DataTransferWCFService.DataTransferService">
|
218
|
+
<endpoint address="" binding="wsDualHttpBinding" contract="DataTransferWCFService.IDataTransferService">
|
219
|
+
<identity>
|
220
|
+
<dns value="localhost" />
|
221
|
+
</identity>
|
222
|
+
</endpoint>
|
223
|
+
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
|
224
|
+
<host>
|
225
|
+
<baseAddresses>
|
226
|
+
<add baseAddress="http://localhost:8733/Design_Time_Addresses/DataTransferWCFService/Service1/" />
|
227
|
+
</baseAddresses>
|
228
|
+
</host>
|
229
|
+
</service>
|
230
|
+
</services>
|
231
|
+
<behaviors>
|
232
|
+
<serviceBehaviors>
|
233
|
+
<behavior>
|
234
|
+
<!-- メタデータ情報の開示を避けるには、
|
235
|
+
展開する前に下の値を false に設定します -->
|
236
|
+
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
|
237
|
+
<!-- デバッグ目的で障害発生時の例外の詳細を受け取るには、
|
238
|
+
下の値を true に設定します。例外情報の開示を避けるには、
|
239
|
+
展開する前に false に設定します -->
|
240
|
+
<serviceDebug includeExceptionDetailInFaults="False" />
|
241
|
+
</behavior>
|
242
|
+
</serviceBehaviors>
|
243
|
+
</behaviors>
|
244
|
+
</system.serviceModel>
|
245
|
+
|
246
|
+
</configuration>
|
247
|
+
|
248
|
+
```
|
249
|
+
|
250
|
+
本体(Program.cs)
|
251
|
+
```C#
|
252
|
+
namespace WCFIPC
|
253
|
+
{
|
254
|
+
class Program
|
255
|
+
{
|
256
|
+
static void Main(string[] args)
|
257
|
+
{
|
258
|
+
//1つ目のプロセスでは
|
259
|
+
Transfer transfer = new Transfer();
|
260
|
+
transfer.Register(new byte[] { 0x12, 0x34, 0x56 });
|
261
|
+
|
262
|
+
//2つ目のプロセスでは
|
263
|
+
DataTransfer.DataTransfer dataTransfer = new DataTransfer.DataTransfer();
|
264
|
+
var response = dataTransfer.GetResponse(0xFF, new byte[] { 0x78, 0x90 });
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
class Transfer
|
269
|
+
{
|
270
|
+
public DataTransfer.DataTransfer service = new DataTransfer.DataTransfer();
|
271
|
+
|
272
|
+
public void Register(byte[] data)
|
273
|
+
{
|
274
|
+
this.service.Register(data);
|
275
|
+
|
276
|
+
//ここでプロセス間のイベントを購読したい
|
277
|
+
this.service.DataTransferServiceInstance.OnCallback += DataTransferServiceInstance_OnCallback;
|
278
|
+
}
|
279
|
+
|
280
|
+
private void DataTransferServiceInstance_OnCallback(object sender, DataTransferWCFService.CommunicationEventArgs args)
|
281
|
+
{
|
282
|
+
Console.Write(args.Message);
|
283
|
+
}
|
284
|
+
|
285
|
+
public void Clear()
|
286
|
+
{
|
287
|
+
this.service.Clear();
|
288
|
+
}
|
289
|
+
}
|
290
|
+
}
|
291
|
+
```
|
292
|
+
|
22
293
|
### 試したこと
|
23
294
|
|
24
295
|
双方向通信
|
25
296
|
|
26
297
|
### 補足情報(FW/ツールのバージョンなど)
|
27
298
|
|
28
|
-
Visual Studio 2019
|
299
|
+
Visual Studio 2019
|
300
|
+
.NET Framework 4.7.2
|