NetPushClient.cs
5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
using HslCommunication.Core.Net;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace HslCommunication.Enthernet
{
/// <summary>
/// 发布订阅类的客户端,使用指定的关键订阅相关的数据推送信息
/// </summary>
/// <remarks>
/// 详细的使用说明,请参照博客<a href="http://www.cnblogs.com/dathlin/p/8992315.html">http://www.cnblogs.com/dathlin/p/8992315.html</a>
/// </remarks>
/// <example>
/// 此处贴上了Demo项目的服务器配置的示例代码
/// <code lang="cs" source="TestProject\HslCommunicationDemo\FormPushNet.cs" region="FormPushNet" title="NetPushClient示例" />
/// </example>
public class NetPushClient : NetworkXBase
{
#region Constructor
/// <summary>
/// 实例化一个发布订阅类的客户端,需要指定ip地址,端口,及订阅关键字
/// </summary>
/// <param name="ipAddress">服务器的IP地址</param>
/// <param name="port">服务器的端口号</param>
/// <param name="key">订阅关键字</param>
public NetPushClient(string ipAddress, int port, string key)
{
endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
keyWord = key;
if (string.IsNullOrEmpty(key))
{
throw new Exception(StringResources.Language.KeyIsNotAllowedNull);
}
}
#endregion
#region NetworkXBase Override
internal override void DataProcessingCenter(AppSession session, int protocol, int customer, byte[] content)
{
if (protocol == HslProtocol.ProtocolUserString)
{
action?.Invoke(this, Encoding.Unicode.GetString(content));
OnReceived?.Invoke(this, Encoding.Unicode.GetString(content));
}
}
internal override void SocketReceiveException(AppSession session, Exception ex)
{
// 发生异常的时候需要进行重新连接
while (true)
{
Console.WriteLine(ex);
Console.WriteLine(StringResources.Language.ReConnectServerAfterTenSeconds);
System.Threading.Thread.Sleep(this.reconnectTime);
if (CreatePush().IsSuccess)
{
Console.WriteLine(StringResources.Language.ReConnectServerSuccess);
break;
}
}
}
#endregion
#region Public Method
/// <summary>
/// 创建数据推送服务
/// </summary>
/// <param name="pushCallBack">触发数据推送的委托</param>
/// <returns>是否创建成功</returns>
public OperateResult CreatePush(Action<NetPushClient, string> pushCallBack)
{
action = pushCallBack;
return CreatePush();
}
/// <summary>
/// 创建数据推送服务,使用事件绑定的机制实现
/// </summary>
/// <returns>是否创建成功</returns>
public OperateResult CreatePush()
{
CoreSocket?.Close();
// 连接服务器
OperateResult<Socket> connect = CreateSocketAndConnect(endPoint, 5000);
if (!connect.IsSuccess) return connect;
// 发送订阅的关键字
OperateResult send = SendStringAndCheckReceive(connect.Content, 0, keyWord);
if (!send.IsSuccess) return send;
// 确认服务器的反馈
OperateResult<int, string> receive = ReceiveStringContentFromSocket(connect.Content);
if (!receive.IsSuccess) return receive;
// 订阅不存在
if (receive.Content1 != 0)
{
connect.Content?.Close();
return new OperateResult(receive.Content2);
}
// 异步接收
AppSession appSession = new AppSession();
CoreSocket = connect.Content;
appSession.WorkSocket = connect.Content;
ReBeginReceiveHead(appSession, false);
return OperateResult.CreateSuccessResult();
}
/// <summary>
/// 关闭消息推送的界面
/// </summary>
public void ClosePush()
{
action = null;
if (CoreSocket != null && CoreSocket.Connected) CoreSocket?.Send(BitConverter.GetBytes(100));
System.Threading.Thread.Sleep(20);
CoreSocket?.Close();
}
#endregion
#region Public Properties
/// <summary>
/// 本客户端的关键字
/// </summary>
public string KeyWord => keyWord;
/// <summary>
/// 获取或设置重连服务器的间隔时间
/// </summary>
public int ReConnectTime { set => reconnectTime = value; get => reconnectTime; }
#endregion
#region Public Event
/// <summary>
/// 当接收到数据的事件信息,接收到数据的时候触发。
/// </summary>
public event Action<NetPushClient, string> OnReceived;
#endregion
#region Private Member
private IPEndPoint endPoint; // 服务器的地址及端口信息
private string keyWord = string.Empty; // 缓存的订阅关键字
private Action<NetPushClient, string> action; // 服务器推送后的回调方法
private int reconnectTime = 10000; // 重连服务器的时间
#endregion
#region Object Override
/// <summary>
/// 返回表示当前对象的字符串
/// </summary>
/// <returns>字符串</returns>
public override string ToString()
{
return $"NetPushClient[{endPoint}]";
}
#endregion
}
}