/// <summary> /// 向运营商服务器验证CP用户名密码 /// </summary> /// <returns></returns> public int Login() { if (socket.IsLogin) { return(0); } lock (socket.Locker) { if (socket.IsLogin) { return(0); } if (!socket.Connected) { socket = SocketManager.Reconnect(socket); } int status = (int)LoginTemplate(); socket.IsLogin = status == 0; if (socket.IsLogin) { if (socket.KeepAlive == null || !socket.KeepAlive.IsAlive) { socket.KeepAlive = KeepAlive(); socket.KeepAlive.Start(socket); } } return(status); } }
/// <summary> /// 向运营商服务器发送短信 /// </summary> /// <param name="phones">手机号列表</param> /// <param name="content">内容</param> /// <returns></returns> public int Submit(string[] phones, string content) { if (!socket.Connected) { socket = SocketManager.Reconnect(socket); } if (!socket.IsLogin) { int status = Login(); if (status != 0) { return(status); } } var messages = PackageMessages(phones, content); if (messages.Length == 1) { return((int)SubmitTemplate(messages[0])); } foreach (var message in messages) { SubmitTemplate(message); } return(0); }
/// <summary> /// 连接 socket /// </summary> /// <param name="host"></param> /// <param name="port"></param> protected SmsConnection(string host, int port, ILog log = null) { _log = log; SocketManager._log = log; socket = SocketManager.Get(host, port, TrafficControl); ServerDataHandler += HandleCap; //m_buffer = new List<byte>(); //messageList = SocketManager.ConnectMessageList; }
/// <summary> /// 向运营商发送链路检测包保持连接 /// </summary> /// <param name="smsSocket"></param> protected override void Heartbeat(SmsSocket smsSocket) { var message = new SmgpActiveTestMessage { SequenceId = NextSequenceId() }; var resp = new SmgpActiveTestRespMessage(SendAndWait(smsSocket, message)); Assert.AreEqual(message.SequenceId, resp.SequenceId); Thread.Sleep(3 * 60 * 1000); // TODO: 配置 }
/// <summary> /// 向运营商发送链路检测包保持连接 /// </summary> /// <param name="smsSocket"></param> protected override void Heartbeat(SmsSocket smsSocket) { var message = new CmppActiveTestMessage { SequenceId = NextSequenceId() }; _log.InfoFormat("心跳数据发送"); var resp = new CmppActiveTestRespMessage(SendAndWait(smsSocket, message)); _log.InfoFormat(string.Format("心跳数据:message:{0}-resp:{1}", message.SequenceId, resp.SequenceId)); Assert.AreEqual(message.SequenceId, resp.SequenceId); //每过一段时间发送一段心跳检测,实际短信网关的心跳检测间隔要小于60,且会主动关闭连接,所以设置为小于60秒的时间间隔 //Thread.Sleep(45 * 1000); // TODO: 配置 不行 Thread.Sleep(20 * 1000); // TODO: 配置 新调整 2018-03-06 }
/// <summary> /// 连接 socket /// </summary> /// <param name="host"></param> /// <param name="port"></param> protected SmsConnection(string host, int port) { socket = SocketManager.Get(host, port, TrafficControl); }
/// <summary> /// 释放资源 /// </summary> public void Dispose() { disposed = true; socket = null; }
/// <summary> /// 异步发送并且等待接收数据完成 /// </summary> /// <param name="smsSocket"></param> /// <param name="message"></param> /// <returns></returns> protected byte[] SendAndWait(SmsSocket smsSocket, SmsMessage message) { if (smsSocket == null) { return(null); } SocketAsyncEventArgs sendArgs; try { smsSocket.WaitTraffic(); lock (((ICollection)sendPool).SyncRoot) { sendArgs = sendPool.Dequeue(); } } catch (InvalidOperationException) // 队列为空 { sendArgs = new SocketAsyncEventArgs(); sendArgs.Completed += AfterSend; } // 发送完加入等待回复的队列 var token = new WaitingDataToken { SequenceId = message.GetSequenceId() }; lock (msgLocker) { messageBuffer.Add(token.SequenceId, token); } sendArgs.AcceptSocket = smsSocket; sendArgs.UserToken = token; var buffer = message.ToBytes(); sendArgs.SetBuffer(buffer, 0, buffer.Length); // 填充要发送的数据 Interlocked.Increment(ref trySending); if (!smsSocket.SendAsync(sendArgs)) // 未异步发送,应当在同步上下文中处理 { AfterSend(null, sendArgs); } WaitHandle.WaitAll(new WaitHandle[] { token.WaitHandle }, 60 * 1000); // 等待异步请求结束 lock (msgLocker) { messageBuffer.Remove(token.SequenceId); } if (token.Bytes == null) { token.SocketError = SocketError.TimedOut; } smsSocket.IsLogin = smsSocket.Connected; if (token.SocketError != SocketError.Success) { throw new SocketException((int)token.SocketError); } return(token.Bytes); }
/// <summary> /// 向运营商发送链路检测包保持连接 /// </summary> /// <param name="smsSocket"></param> protected abstract void Heartbeat(SmsSocket smsSocket);
/// <summary> /// 异步发送并且等待接收数据完成 此方法存在如果一条消息超时了导致后面所有的消息都会超时 /// </summary> /// <param name="smsSocket"></param> /// <param name="message"></param> /// <returns></returns> protected byte[] SendAndWait(SmsSocket smsSocket, SmsMessage message) { if (smsSocket == null) { return(null); } //if (!socket.Connected) if (!SocketManager.IsSocketConnected(smsSocket)) { _log.InfoFormat("Socket未连接-SendAndWait"); //return null; //socket = SocketManager.Reconnect(socket); //messageList.Add(string.Format("{0}:Socket未连接-SendAndWait", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"))); } if (!smsSocket.IsLogin) { _log.InfoFormat("Socket未登录-SendAndWait"); //messageList.Add(string.Format("{0}:Socket未登录-SendAndWait", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"))); } SocketAsyncEventArgs sendArgs; try { smsSocket.WaitTraffic(); lock (((ICollection)sendPool).SyncRoot) { sendArgs = sendPool.Dequeue(); } } catch (InvalidOperationException) // 队列为空 { sendArgs = new SocketAsyncEventArgs(); sendArgs.Completed += AfterSend; } // 发送完加入等待回复的队列 var token = new WaitingDataToken { SequenceId = message.GetSequenceId() }; lock (msgLocker) { messageBuffer.Add(token.SequenceId, token); } sendArgs.AcceptSocket = smsSocket; sendArgs.UserToken = token; var buffer = message.ToBytes(); sendArgs.SetBuffer(buffer, 0, buffer.Length); // 填充要发送的数据 Interlocked.Increment(ref trySending); if (!smsSocket.SendAsync(sendArgs)) // 未异步发送,应当在同步上下文中处理 { AfterSend(null, sendArgs); } //_log.InfoFormat("等待:{0}", token.SequenceId); WaitHandle.WaitAll(new WaitHandle[] { token.WaitHandle }, 60 * 1000); // 等待异步请求结束 65 * 1000 //_log.InfoFormat("收到:{0}", token.SequenceId); lock (msgLocker) { messageBuffer.Remove(token.SequenceId); } if (token.Bytes == null) { token.SocketError = SocketError.TimedOut; } smsSocket.IsLogin = smsSocket.Connected; if (token.SocketError != SocketError.Success) { throw new SocketException((int)token.SocketError); } return(token.Bytes); }