2013-05-09 49 views
4

我想发送SMS批量用户(4000用户)的,所以我把下面的方法对环:发送SMS用于大宗用户

protected int SendSMS(string url) 
     { 
      // Now to Send Data. 

      StreamWriter writer = null; 
      StringBuilder postData = new StringBuilder(); 
      Uri myUri = new Uri(url); 
      postData.Append(HttpUtility.ParseQueryString(myUri.Query).Get("Username")); 
      postData.Append(HttpUtility.ParseQueryString(myUri.Query).Get("Password")); 
      postData.Append(HttpUtility.ParseQueryString(myUri.Query).Get("Sender")); 
      postData.Append(HttpUtility.ParseQueryString(myUri.Query).Get("Recipients")); 
      postData.Append(HttpUtility.ParseQueryString(myUri.Query).Get("MessageData")); 



      string webpageContent = string.Empty; 
      byte[] byteArray = Encoding.UTF8.GetBytes(postData.ToString()); 
      HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); 
      webRequest.Method = "POST"; 
      webRequest.ContentType = "application/x-www-form-urlencoded"; 
      webRequest.ContentLength = webRequest.ContentLength = byteArray.Length; 

      writer = new StreamWriter(webRequest.GetRequestStream()); 


      try 
      { 
       using (Stream webpageStream = webRequest.GetRequestStream()) 
       { 
        webpageStream.Write(byteArray, 0, byteArray.Length); 
       } 

       using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) 
       { 
        using (StreamReader reader = new StreamReader(webResponse.GetResponseStream())) 
        { 
         webpageContent = reader.ReadToEnd(); 
         //TODO:parse webpagecontent: iF response contains "OK" 
         if (webpageContent.Contains("OK")) return 1; 
         else return 0; 
        } 
       } 
       //return 1; 

      } 
      catch (Exception ee) 
      { 
       ErrMapping.WriteLog(url); 
       string error = ee.Message + "<br><br>Stack Trace : " + ee.StackTrace; 
       ErrMapping.WriteLog(error); 
       return -1; 
      } 

     } 

用户的像65的特定数目后用户没有sms已被送往用户的休息和

我得到以下异常:

Error Message:Thread was being aborted.<br><br>Stack Trace : at System.Net.UnsafeNclNativeMethods.OSSOCK.recv(IntPtr socketHandle, Byte* pinnedBuffer, Int32 len, SocketFlags socketFlags) 
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, SocketError& errorCode) 
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) 
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) 
    at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) 
    at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead) 
    at System.Net.ConnectStream.ProcessWriteCallDone(ConnectionReturnResult returnResult) 
    at System.Net.HttpWebRequest.CheckDeferredCallDone(ConnectStream stream) 
    at System.Net.HttpWebRequest.GetResponse() 
    at SendSMS_EmailUI.Frm_SMS_send.SendSMS(String url) 
+0

只要服务器中止查询,尝试查看发送短信时服务器是否高负载,祝您好运! – Obama 2013-05-09 11:52:52

+0

谁是短信提供商?你也可以发布循环代码吗? – nmat 2013-05-11 14:18:36

+0

@nmat:我只需要在for循环(用户数量)中调用以前的方法来发送短信。 – 2013-05-12 05:48:39

回答

6

我建立了一个SMS门户。你所描述的在我的应用程序的v1.0中也经历过。解决方案是让我的短信网关通过HTTP为我提供批量短信访问。我可以将多达1000个目的地放入XML(或逗号分隔)包中并发送到批量短信网关。因为我在共享主机上运行,​​所以我将其限制在500个目的地。

我有一个缓存/临时存储/表,其中我在某些情况下批量处理大型目标(高达1,000,000),并且一个调度程序(基于定时器)每隔几秒发送一批500(通过重复调用脚本)消息被发送。像魅力一样工作!

对于个性化消息,我鼓励客户端在转发到我的SMS门户之前使用我的桌面应用程序进行个性化。祝你好运

过程:

你需要三个项目

  1. 接收SendSMS要求
  2. 发送短信指令码,
  3. 调度器/定时器( Script/Host Service)

A.在发送短信请求到达与

a. The Message and Sender ID/ Sender GSM Number. 

b. The Destinations (as a comma delimited list). We'll assume 10,000 destinations 

B.拆分目的地到500(任何你想要的大小),并记录500个目的地,在每个INBOX行/记录的信息和SenderID一起。 注意:如果通过循环(10,000次循环)计算500次,脚本可能会超时。我国的GSM号码是13位数字。 所以我做长500(13 + 1)的环子路线,让每批次500个目的地(20圈)。*

C.电话发送短信的脚本。发送第一个500并将消息标记为已发送。您可以添加时间发送。启动调度程序

D.调度程序每隔1.5分钟检查一次INBOX中是否存在未发送的消息并发送它。如果没有,Scheduler停止。 因此,在30分钟内发送10,000条消息

+0

请举例说明一下吗? – 2013-05-18 14:56:19

6

恕我直言,这将代表应用程序的情况下进行的批量操作,可以很容易地通过下面的步骤

  1. 当群发短信被触发完成后,详细信息将在数据库表
  2. 一个窗口中输入服务将不断监控此表的任何更新
  3. 当Windows服务发现新条目时,它将花费几百条记录,然后发送它们。批量处理。
  4. 在后续请求之间可能会有延迟。
  5. 这将确保您跟踪哪些订单项已失败,并且不会使用批量数据堵塞服务器。

这是建议最广泛的方法。

请提供您对此实施的意见。

3

检查,如果你的StreamWriter是越来越布置

using (StreamWriter writer = new StreamWriter(webRequest.GetRequestStream())) 
{ 

} 
5

我们做一些类似建议什么沙拉湾的电子邮件的东西,并怀疑它会工作的短信。

基本上,我们的Web服务器上运行的服务一次只发送x,并且每次发送之间都存在自定义延迟y。 它可以在不到10分钟的时间内发送两千个数据,既不占用CPU也不占用带宽。

一些技巧,都不在我们原来的设计要牢记:

  1. 有办法手动停止所有发送(见下提示)

  2. 具有用户友好的方式来终止一个特定的消息。如果您的代码(或用户)意外地发送了相同的东西五次,您需要一种快速中止的方法。

  3. 对两个数字都使用配置文件(上面x & y),因此您可以在不进行重新部署的情况下进行调整。我认为y延迟是50毫秒。

在您决定将同一邮件捆绑到多个收件人之前,请确保智能手机无法回复其捆绑中的其他人。

HTH,

克里斯C.

+0

嗨克里斯, 正如提示[3]中提到的,我们有来自配置文件的x和y,并且不需要重新部署。 我们确实有一种机制,可以从服务中发送失败的机制,然后向用户显示,以便他可以选择再次发送失败的机制。 – Saravanan 2013-05-18 17:05:21

3

可以在缓冲值满了,请检查一下,并把它的最大值在网络配置文件

2

也许你正在Web请求太快:尽量减缓下来,以排除时序问题,例如增加睡眠:

System.Threading.Thread.Sleep(1000); 

1000毫秒= 1秒只是一个提示,你应该尝试不同的值,看看是否如此mething变化

5

我怀疑问题是,因为你在一个asp.net网站,这是一个长期运行的任务,它是超时的响应。

这个超时值在web.config中被控制,它的默认值被设置为110秒。将此数字增加到更长的数字,看看它是否开始工作。

<system.web> 
    <!-- 600 seconds = 10 minute timeout ---> 
    <httpRuntime executionTimeout="600"/> 
    </system.web> 

一个更好的方法是使用一个单独的线程并返回的进度 给用户的更新,虽然这将是更加复杂,但最终更可靠。

请参阅Parallel.ForEach以简化此过程的线程。

Msdn - httpRuntime documention

5

这不回答你原来的问题,但相关的有用的信息。一旦你解决了这个问题,你可能会遇到另一个问题 - 电信公司通常会阻止批量发送的短信作为抑制短信垃圾邮件的一种方式。如果您将以商业规模实施此项目,您需要向移动营销协会提交一份摘要,并获得批准,这可能需要相当长的时间。