前两章分别讲了Socket的数据传输,本章开始将在前两章的基础上构建一个消息传输机制.
因为服务端和客户端都离不开消息的传输,所以先讲如何在前两章的基础上构建消息传输的信道,本例构造了一个类MessageSession,该类负责消息在网络中传送,并且该类实现了一个接口IMessageSession,其目的同前一章实现接口的目的一样,都是为了方便以后的扩展,该类的主要传输主体为一个接口IMessage,可以说这是一个消息调用的接口,是为了远程调用而定义的一个接口,本篇中先给出它的接口定义,其实现在后续章节中给出
IMessage接口的定义如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace YZKStdLibrary.Message
7 {
8 /// <summary>
9 /// 消息接口
10 /// </summary>
11 public interface IMessage
12 {
13 /// <summary>
14 /// 在服务进程中的消息唯一ID
15 /// </summary>
16 long MessageID { get; }
17 /// <summary>
18 /// 获取登录凭证,该凭证为经过服务端验证的唯一标识
19 /// </summary>
20 string LoginedAuthentication { get; }
21 /// <summary>
22 /// 获取调用成员名称或Guid
23 /// </summary>
24 string InvokeMemberGuid { get; }
25 /// <summary>
26 /// 获取处理该消息的服务类标识,使用该标识确定是哪个服务类处理该消息
27 /// </summary>
28 string ServiceGuid { get; }
29 /// <summary>
30 /// 获取处理该消息的程序集
31 /// </summary>
32 string AssemblyGuid { get; }
33 /// <summary>
34 /// 消息参数数组
35 /// </summary>
36 object[] Paramets { get; }
37 }
38 }
同时还定义了一个传输进度的回调代理OnTransingCallback:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /// <summary>
2 /// 传输进度回调
3 /// </summary>
4 /// <param name="transesize">要传输的数据的字节数</param>
5 /// <param name="tranfferedbytes">已传输的字节数</param>
6 /// <param name="message">传输的消息</param>
7 /// <param name="transedirection">传输方向</param>
8 public delegate void OnTransingCallback(long transesize, long tranfferedbytes, IMessage message, DataTranseDirection transedirection);
该类定义了三个异步传输方法,由于使用IAsyncResult的返回机制,所以没有定义同不方法,要同步只需等待返回的完成信号即可,当然你也可以定义同步方法,这个在前一章的同步方法上构建比教简单,有兴趣的网友可以自己试试.三个异步传输方法分别是BeginTranseMessage,BeginSendMessage,BeginReceiveMessage,同时它们都对应一个结束方法EndTranseMessage,EndSendMessage,EndReceiveMessage,下面分别先说一下这三个方法的用途.
BeginTranseMessage:一般使用在客户端操作,也就是使用在发送完数据并且等待响应数据的应用场景下,大家可以想一下,客户端的调用一般都是一发一收的,即使是过程调用没有返回数据你也应该返回一个调用结束的消息通知调用方是否成功调用或返回一个错误通知错误信息.
BeginSendMessage和BeginReceiveMessage;一般使用在服务端,也就是在先接收消息再返回消息响应的应用场景下.
下面讲一下这三个方法:
BeginTranseMessageCore:先获取参数ITranseParamets,并将它设置成发送的状态,再设置传输时使用的流类型SR_StreamTypeEnum,然后开始数据传输,这里就涉及到接口ITranseParamets的实现类MessageTranseParamets
这个类在三个异步传输方法中都要用到,因此先讲讲这个类:MessageTranseParamets
SR_StreamType属性:定义传输流的类型
WaitReceiveMessage属性:定义是否等待消息响应
AsyncResult属性:一个IAsyncResult接口的实现
p_Serialize变量:一个序列化接口的对象,该序列化接口是自定义的,当然也可以使用MS本身的序列化
p_BufferIndexe变量:这是一个使用的缓冲区索引的结构,该结构的目的是指明使用的缓冲区的开始索引和长度,由于本例是从一个更大的应用中摘录的,在该应用中定义了一个缓冲区机制,即所有使用位数组的场景都使用同一个大的位数组,它是一开始就创建好的,使用者通过一些方法获取它的可用开始索引和长度后使用,本例中的位数组流和传输缓冲区都是使用这样一个机制.至于如何实现请网友们等待后续文章.
g_TempFileName变量:文件流的文件名称
Message属性:要发送的消息主体
TransingCallback属性:传输进度回调代理
其它接口的属性我就不讲了,请参看上一章接口的定义.
TranseBuffer,TranseBufferOffset,TranseBufferSize大家先用new byte[]和0,byte[].Length代替
ResetToSendParamets方法:将参数设置成等待发送的状态,该方法就是初始化发送时的参数,并且调用InitSendMessage方法初始化发送流,流的类型取决于属性SR_StreamType,对于Auto默任使用位数组流,对于创建位数组流CreateBytesStream方法中的类型BytesBufferStream已说过在后续章节中给出,大家不妨先用CreateBytesStream2使用MemoryStream代替.并且将消息序列化到流中(此时可以根据约定进行加密或压缩等操作),大家请注意了在InitSendMessage方法中最后设置了传输约定中的ITranseHeader.TranseSize和传输流的位置
ResetToRcvParamets方法:将参数设置成等待接收的状态.
ChangeToRcvParamets方法:将参数送发送状态转为接收状态
ResetToConnectParamets方法:将参数设置成连接状态
HeaderTransed方法:该方法是接口中定义的方法,用于通讯模块通知本接口约定已传输完成,在前一章中使用到本方法,
在该方法中首先将约定已传输标识置位,并且如果是接收操作则根据约定初始化接收流,接收流的初始化也是根据SR_StreamType属性创建的,所以发送和接收双方都应该使用同一个SR_StreamType的值.同样在没有给出BytesBufferStream流的定义之前,大家先用MemoryStream代替
AsyncTranseOver方法:该方法是接口中定义的方法,用于通讯模块通知本接口数据主体已传输完成,在前一章中使用到本方法,在该方法中如果是连接则直接调用连接完成的回调就完事,如果是接收则反序列化对象(此时可以根据约定进行解密或解压等操作),最后完成传输(调用MessageSession.FinshSession方法)
AsyncNotyTransing:该方法是接口中定义的方法,用于通讯模块通知本接口约定已传输完成,在前一章中使用到本方法,用于接收传输进度的通知,本例只是简单调用OnTransingCallback回调(如果不为null的话)就完事,
以下为该类的定义:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using YZKStdLibrary.Network.Transe;
6 using System.Net;
7 using System.Threading;
8 using System.IO;
9 using System.IO.MemoryMappedFiles;
10 using YZKStdLibrary.IO;
11 using YZKStdLibrary.Serialize;
12
13 namespace YZKStdLibrary.Message.Channel
14 {
15 internal class MessageTranseParamets : ITranseParamets
16 {
17
18 public MessageTranseParamets()
19 {
20 p_TranseHeader = new TranseHeader();
21 p_AsyncResult = new MessageSessionAsyncResult(null, null);
22 p_SR_StreamType = SR_StreamTypeEnum.Auto;
23 }
24
25 private SR_StreamTypeEnum p_SR_StreamType;
26
27 public SR_StreamTypeEnum SR_StreamType
28 {
29 get { return p_SR_StreamType; }
30 set { p_SR_StreamType = value; }
31 }
32
33 private bool p_WaitReceiveMessage;
34
35 public bool WaitReceiveMessage
36 {
37 get { return p_WaitReceiveMessage; }
38 }
39
40 private MessageSession g_Owner;
41
42 private MessageSessionAsyncResult p_AsyncResult;
43
44 internal MessageSessionAsyncResult AsyncResult
45 {
46 get { return p_AsyncResult; }
47 }
48
49 private IFormattSerialize p_Serialize;
50
51 private BufferIndexHandle p_BufferIndexe;
52
53 private string g_TempFileName;
54
55 private void DeleteTempFile()
56 {
57 if (!string.IsNullOrEmpty(g_TempFileName))
58 {
59 StandHelperMethod.DeleteFile(g_TempFileName);
60 g_TempFileName = null;
61 }
62 }
63
64 private void CloseStream()
65 {
66 if (p_TranseStream != null)
67 {
68 try
69 {
70 p_TranseStream.Close();
71 }
72 catch { }
73 try
74 {
75 p_TranseStream.Dispose();
76 }
77 catch { }
78 p_TranseStream = null;
79 }
80 }
81
82 private void CreateMappFileStream()
83 {
84 g_TempFileName = MessageHelper.GetTempFileName();
85 //MemoryMappedFile mp = MemoryMappedFile.CreateFromFile(g_TempFileName, FileMode.Create, null, 5 * 1024 * 1024);
86 //p_TranseStream = mp.CreateViewStream();
87 //mp.Dispose();
88 p_TranseStream = new FileStream(g_TempFileName, FileMode.Create);
89 }
90
91 private void CreateBytesStream()
92 {
93 p_TranseStream = new BytesBufferStream(MessageHelper.StreamBuffer);
94 }
95
96 private void CreateBytesStream2()
97 {
98 p_TranseStream = new MemoryStream();
99 }
100
101 private IMessage p_Message;
102
103 public IMessage Message
104 {
105 get { return p_Message; }
106 }
107
108 private OnTransingCallback p_TransingCallback;
109
110 public OnTransingCallback TransingCallback
111 {
112 get { return p_TransingCallback; }
113 }
114
115 private bool TrySerializeMessage(IMessage message)
116 {
117 try
118 {
119 p_Serialize.Serialize(p_TranseStream, message);
120 }
121 catch (BytesBufferManagerAssignException)
122 {
123 return false;
124 }
125 catch (Exception e)
126 {
127 p_TranseError = e;
128 }
129 return true;
130 }
131
132 private bool InitSendMessage(IMessage message)
133 {
134 try
135 {
136 switch (p_SR_StreamType)
137 {
138 case SR_StreamTypeEnum.Auto:
139 {
140 CreateBytesStream();
141 if (!TrySerializeMessage(message))
142 {
143 CloseStream();
144 CreateMappFileStream();
145 TrySerializeMessage(message);
146 }
147 break;
148 }
149 case SR_StreamTypeEnum.Bytes:
150 {
151 CreateBytesStream();
152 p_Serialize.Serialize(p_TranseStream, message);
153 break;
154 }
155 case SR_StreamTypeEnum.Files:
156 {
157 CreateMappFileStream();
158 p_Serialize.Serialize(p_TranseStream, message);
159 break;
160 }
161 }
162 }
163 catch (Exception e)
164 {
165 p_TranseError = e;
166 }
167
168 if (p_TranseError != null)
169 return false;
170 p_Message = message;
171 p_TranseHeader.TranseSize = p_TranseStream.Length;
172 p_TranseStream.Seek(0, SeekOrigin.Begin);
173 return true;
174 }
175
176 private void InitReceiveStream()
177 {
178 long x = p_TranseHeader.TranseSize;
179 switch (p_SR_StreamType)
180 {
181 case SR_StreamTypeEnum.Auto:
182 {
183 if (x < MessageHelper.StreamBuffer.TotalBytesCount)
184 {
185 BufferIndexHandle bh;
186 if (x <= 0)
187 bh = MessageHelper.StreamBuffer.TryAssignBufferHandle();
188 else
189 bh = MessageHelper.StreamBuffer.TryAssignBufferHandle((int)x);
190 if (!bh.IsEmpty)
191 {
192 p_TranseStream = new BytesBufferStream(
193 MessageHelper.StreamBuffer,
194 bh,
195 0, true, true, true, true);
196 //((BytesBufferStream)p_TranseStream).InitFixStream();
197 }
198 else
199 CreateMappFileStream();
200 }
201 else
202 {
203 CreateMappFileStream();
204 }
205 break;
206 }
207 case SR_StreamTypeEnum.Bytes:
208 {
209 BufferIndexHandle bh;
210 if (x <= 0)
211 bh = MessageHelper.StreamBuffer.TryAssignBufferHandle();
212 else
213 bh = MessageHelper.StreamBuffer.TryAssignBufferHandle((int)x);
214 if (!bh.IsEmpty)
215 {
216 p_TranseStream = new BytesBufferStream(
217 MessageHelper.StreamBuffer,
218 bh,
219 0, true, true, true,true);
220 //((BytesBufferStream)p_TranseStream).InitFixStream();
221 }
222 break;
223 }
224 case SR_StreamTypeEnum.Files:
225 {
226 CreateMappFileStream();
227 break;
228 }
229 }
230
231 }
232
233 private void DeSerializeRcvMessage()
234 {
235 p_TranseStream.Seek(0, SeekOrigin.Begin);
236 p_AsyncResult.Response =
237 p_Serialize.DeSerialize(p_TranseStream) as IMessage;
238 }
239
240 #region ITranseParamets 成员
241
242 private TranseHeader p_TranseHeader;
243
244 public ITranseHeader TranseHeader
245 {
246 get { return p_TranseHeader; }
247 }
248
249 private Stream p_TranseStream;
250
251 public Stream TranseStream
252 {
253 get { return p_TranseStream; }
254 }
255
256 public byte[] TranseBuffer
257 {
258 get { return MessageHelper.ReadWriteBuffer.Buffer; }
259 }
260
261 public int TranseBufferOffset
262 {
263 get { return p_BufferIndexe.Index; }
264 }
265
266 public int TranseBufferSize
267 {
268 get { return p_BufferIndexe.Count; }
269 }
270
271 private long p_BytesTransferred;
272
273 public long BytesTransferred
274 {
275 get
276 {
277 return p_BytesTransferred;
278 }
279 set
280 {
281 p_BytesTransferred = value;
282 }
283 }
284
285 private bool p_IsAsyncTranse;
286
287 public bool IsAsyncTranse
288 {
289 get { return p_IsAsyncTranse; }
290 set { p_IsAsyncTranse = value; }
291 }
292
293 private DataTranseDirection p_DataTranseDirection;
294
295 public DataTranseDirection DataTranseDirection
296 {
297 get { return p_DataTranseDirection; }
298 }
299
300 private Exception p_TranseError;
301
302 public Exception TranseError
303 {
304 get
305 {
306 return p_TranseError;
307 }
308 set
309 {
310 p_TranseError = value;
311 }
312 }
313
314 private bool p_IsCancel;
315
316 public bool IsCancel
317 {
318 get { return p_IsCancel; }
319 }
320
321 private bool p_HeaderTransedOver;
322
323 public bool HeaderTransedOver
324 {
325 get { return p_HeaderTransedOver; }
326 }
327
328 private EndPoint p_ConnectToEndPoint;
329
330 public EndPoint ConnectToEndPoint
331 {
332 get { return p_ConnectToEndPoint; }
333 }
334
335 private object p_ConnectTranseInterfaceSetting;
336
337 public object ConnectTranseInterfaceSetting
338 {
339 get { return p_ConnectTranseInterfaceSetting; }
340 }
341
342 public void HeaderTransed()
343 {
344 p_HeaderTransedOver = true;
345 if (p_DataTranseDirection == DataTranseDirection.ReceivingData)
346 {
347 InitReceiveStream();
348 }
349 }
350
351 public void AsyncTranseOver()
352 {
353 if (p_DataTranseDirection == Network.Transe.DataTranseDirection.Connecting)
354 {
355 if (p_Cb != null)
356 p_Cb(this);
357 return;
358 }
359 if (p_TranseError == null)
360 {
361 if (p_DataTranseDirection == Network.Transe.DataTranseDirection.ReceivingData)
362 {
363 try
364 {
365 DeSerializeRcvMessage();
366 }
367 catch (Exception e)
368 {
369 p_TranseError = e;
370 }
371 }
372 }
373 if (g_Owner != null)
374 g_Owner.FinshSession(this);
375 }
376
377 public void AsyncNotyTransing()
378 {
379 if (p_TransingCallback != null)
380 p_TransingCallback(p_TranseHeader.TranseSize, p_BytesTransferred, p_Message, p_DataTranseDirection);
381 }
382
383 #endregion
384
385 internal void ResetToNull(bool asyncrest)
386 {
387 CloseStream();
388 DeleteTempFile();
389 MessageHelper.ReadWriteBuffer.RecoveryBufferHandle(p_BufferIndexe);
390 p_BufferIndexe = BufferIndexHandle.Empty;
391 if (asyncrest)
392 p_AsyncResult.ResetToNull();
393 else
394 p_AsyncResult = null;
395 p_Serialize = null;
396 p_BytesTransferred = 0;
397 p_DataTranseDirection = DataTranseDirection.Unkown;
398 p_IsAsyncTranse = false;
399 p_TranseError = null;
400 p_IsCancel = false;
401 p_HeaderTransedOver = false;
402 p_ConnectToEndPoint = null;
403 p_ConnectTranseInterfaceSetting = null;
404 p_TransingCallback = null;
405 p_Message = null;
406 p_TranseHeader.RecyValue();
407 g_Owner = null;
408 p_WaitReceiveMessage = false;
409 p_Cb = null;
410 }
411
412 internal bool ResetToSendParamets(
413 MessageSession owner,
414 IMessage sendmessage,
415 int headerflag,
416 object state,
417 AsyncCallback callback,
418 OnTransingCallback tccbk,
419 bool waitrcvmsg)
420 {
421 g_Owner = owner;
422 p_BufferIndexe = MessageHelper.ReadWriteBuffer.AssignBufferHandle();
423 p_Serialize = CurrentAppConfiger.CurrentErpConfinger.Formattor;
424 if (p_AsyncResult == null)
425 p_AsyncResult = new MessageSessionAsyncResult(state, callback);
426 else
427 p_AsyncResult.Reset(state, callback);
428 p_DataTranseDirection = Network.Transe.DataTranseDirection.SendingData;
429 p_IsAsyncTranse = true;
430 p_TransingCallback = tccbk;
431 p_TranseHeader.TranseFlags = headerflag;
432 p_WaitReceiveMessage = waitrcvmsg;
433 return InitSendMessage(sendmessage);
434 }
435
436 internal void ResetToRcvParamets(
437 MessageSession owner,
438 int headerflag,
439 object state,
440 AsyncCallback callback,
441 OnTransingCallback tccbk)
442 {
443 g_Owner = owner;
444 p_BufferIndexe = MessageHelper.ReadWriteBuffer.AssignBufferHandle();
445 p_Serialize = CurrentAppConfiger.CurrentErpConfinger.Formattor;
446 if (p_AsyncResult == null)
447 p_AsyncResult = new MessageSessionAsyncResult(state, callback);
448 else
449 p_AsyncResult.Reset(state, callback);
450 p_DataTranseDirection = Network.Transe.DataTranseDirection.ReceivingData;
451 p_IsAsyncTranse = true;
452 p_TransingCallback = tccbk;
453 p_TranseHeader.TranseFlags = headerflag;
454 p_WaitReceiveMessage = false;
455 }
456
457 internal void ChangeToRcvParamets()
458 {
459 CloseStream();
460 DeleteTempFile();
461 p_Cb = null;
462 p_BytesTransferred = 0;
463 p_DataTranseDirection = DataTranseDirection.ReceivingData;
464 p_IsAsyncTranse = true;
465 p_TranseError = null;
466 p_IsCancel = false;
467 p_HeaderTransedOver = false;
468 p_ConnectToEndPoint = null;
469 p_ConnectTranseInterfaceSetting = null;
470 p_Message = null;
471 p_TranseHeader.TranseSize = 0;
472 p_WaitReceiveMessage = false;
473 }
474
475 internal void ResetToConnectParamets(
476 IMessage sendmessage,
477 EndPoint ep,
478 ConnectCallback cb,
479 object facesetting,
480 object state,
481 OnTransingCallback tccbk)
482 {
483 p_TransingCallback = tccbk;
484 p_IsAsyncTranse = true;
485 p_ConnectToEndPoint = ep;
486 p_DataTranseDirection = Network.Transe.DataTranseDirection.Connecting;
487 p_ConnectTranseInterfaceSetting = facesetting;
488 p_Cb = cb;
489 p_Message = sendmessage;
490 if (p_AsyncResult == null)
491 p_AsyncResult = new MessageSessionAsyncResult(state, null);
492 else
493 p_AsyncResult.Reset(state, null);
494 }
495
496 private ConnectCallback p_Cb;
497 }
498
499 internal class MessageSessionAsyncResult : IAsyncResult,IDisposable
500 {
501
502 internal MessageSessionAsyncResult(object state,AsyncCallback callback)
503 {
504 p_AsyncState = state;
505 p_CompletedSynchronously = false;
506 p_IsCompleted = false;
507 p_Callback = callback;
508 p_AsyncWaitHandle = null;
509 g_WaitLock = new object();
510 }
511
512 private object p_AsyncState;
513
514 private bool p_CompletedSynchronously;
515
516 private bool p_IsCompleted;
517
518 private AsyncCallback p_Callback;
519
520 private ManualResetEvent p_AsyncWaitHandle;
521
522 private object g_WaitLock;
523
524 #region IAsyncResult 成员
525
526 public object AsyncState
527 {
528 get { return p_AsyncState; }
529 }
530
531 public WaitHandle AsyncWaitHandle
532 {
533 get
534 {
535 lock (g_WaitLock)
536 {
537 if (p_AsyncWaitHandle == null)
538 p_AsyncWaitHandle = new ManualResetEvent(false);
539 return p_AsyncWaitHandle;
540 }
541 }
542 }
543
544 public bool CompletedSynchronously
545 {
546 get { return p_CompletedSynchronously; }
547 }
548
549 public bool IsCompleted
550 {
551 get { return p_IsCompleted; }
552 }
553
554 #endregion
555
556 internal bool SetHandle()
557 {
558 p_IsCompleted = true;
559 bool set = false;
560 lock (g_WaitLock)
561 {
562 if (p_AsyncWaitHandle != null)
563 {
564 p_AsyncWaitHandle.Set();
565 set = true;
566 }
567 }
568 if (!set)
569 {
570 if (p_Callback != null)
571 p_Callback(this);
572 }
573 return set;
574 }
575
576 #region IDisposable 成员
577
578 public void Dispose()
579 {
580 lock (g_WaitLock)
581 {
582 if (p_AsyncWaitHandle != null)
583 {
584 try
585 {
586 p_AsyncWaitHandle.Close();
587 }
588 catch { }
589 try
590 {
591 p_AsyncWaitHandle.Dispose();
592 }
593 catch { }
594 p_AsyncWaitHandle = null;
595 }
596 }
597 }
598
599 #endregion
600
601 private IMessage p_Response;
602
603 internal IMessage Response
604 {
605 get { return p_Response; }
606 set { p_Response = value; }
607 }
608
609 internal void ResetToNull()
610 {
611 Dispose();
612 p_AsyncState = null;
613 p_CompletedSynchronously = false;
614 p_IsCompleted = false;
615 p_Callback = null;
616 p_Response = null;
617 p_Error = null;
618 p_ConnecteFace = null;
619 p_Session = null;
620 }
621
622 internal void Reset(object state, AsyncCallback callback)
623 {
624 p_AsyncState = state;
625 p_Callback = callback;
626 p_IsCompleted = false;
627 }
628
629 private Exception p_Error;
630
631 internal Exception Error
632 {
633 get { return p_Error; }
634 set { p_Error = value; }
635 }
636
637 private ITranseInterface p_ConnecteFace;
638
639 internal ITranseInterface ConnectFace
640 {
641 get { return p_ConnecteFace; }
642 set { p_ConnecteFace = value; }
643 }
644
645 private IMessageSession p_Session;
646
647 internal IMessageSession Session
648 {
649 get { return p_Session; }
650 set { p_Session = value; }
651 }
652 }
653 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 public enum SR_StreamTypeEnum
2 {
3 /// <summary>
4 /// 自动选择
5 /// </summary>
6 Auto,
7 /// <summary>
8 /// 位数组流
9 /// </summary>
10 Bytes,
11 /// <summary>
12 /// 文件流
13 /// </summary>
14 Files
15 }
16
17 internal delegate void ConnectCallback(MessageTranseParamets par);
BeginSendMessage方法:它和BeginTranseMessage方法一样,只不过对waitrcv传进False,也就是说该方法不等响应一旦发送完成就调用回调,而BeginTranseMessage方法要等待响应接收完成后再调用回调.
BeginReceiveMessage方法:它将参数ITranseParamets设为接收状态后就开始等待接收数据,接收完成后就调用回调.
由于存在BeginSendMessage和BeginReceiveMessage方法,使用方可以进行N次发送和接收,这都是根据具体应用而定的,所以提供了Close和WaitClose方法由使用方负责在适当的时机关闭信道.
下面是IMessage接口定义,先贴出来:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace YZKStdLibrary.Message
7 {
8 /// <summary>
9 /// 消息接口
10 /// </summary>
11 public interface IMessage
12 {
13 /// <summary>
14 /// 在服务进程中的消息唯一ID
15 /// </summary>
16 long MessageID { get; }
17 /// <summary>
18 /// 获取登录凭证,该凭证为经过服务端验证的唯一标识
19 /// </summary>
20 string LoginedAuthentication { get; }
21 /// <summary>
22 /// 获取调用成员名称或Guid
23 /// </summary>
24 string InvokeMemberGuid { get; }
25 /// <summary>
26 /// 获取处理该消息的服务类标识,使用该标识确定是哪个服务类处理该消息
27 /// </summary>
28 string ServiceGuid { get; }
29 /// <summary>
30 /// 获取处理该消息的程序集
31 /// </summary>
32 string AssemblyGuid { get; }
33 /// <summary>
34 /// 消息参数数组
35 /// </summary>
36 object[] Paramets { get; }
37 }
38 }
OK,这一章就先到这了.