4

我想发送SMS给大量用户(4000 个用户),所以我将以下方法放在循环中:

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) 
4

8 回答 8

7

恕我直言,将代表应用程序执行的批量操作可以通过以下过程轻松完成

  1. 触发群发短信时,详细信息将输入数据库表中
  2. Windows 服务将不断监视此表的任何更新
  3. 当windows服务找到新条目时,它将需要几百条记录,然后发送它们。批量处理。
  4. 后续请求之间可能存在延迟。
  5. 这将确保您跟踪哪些订单项失败,并且不会因大量数据而阻塞服务器。

这是最广泛建议的方法。

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

于 2013-05-12T14:41:49.740 回答
6

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

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

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

过程:

你需要三样东西

  1. 接收 SendSMS 请求的脚本
  2. 发送短信的脚本
  3. 调度程序/定时器(脚本/主机服务)

A. 发送 SMS 请求到达

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 个目的地连同消息和 SenderID 一起记录在每个收件箱行/记录中。 注意:如果您通过循环计数 500(10,000 个循环),则脚本可能会超时。我国的 GSM 号码是 13 位数字。所以我做了一个长度为 500 (13+1) 的循环子字符串,以获得每批 500 个目的地(20 个循环)。*

C. 调用发送 SMS 的脚本。发送前 500 条消息并将消息标记为已发送。您可以添加发送时间。启动调度程序

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

于 2013-05-18T04:39:41.503 回答
5

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

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

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

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

请参阅Parallel.ForEach了解线程处理此过程的简单方法。

Msdn - httpRuntime 文档

于 2013-05-17T14:05:41.387 回答
5

这不是回答您的原始问题,而是相关的有用信息。一旦你解决了这个问题,你可能会遇到另一个问题——电信公司通常会阻止批量发送的 SMS 消息,以此来抑制 SMS 垃圾邮件。如果您将在商业规模上这样做,您需要向移动营销协会提交一份简报,并获得他们的批准,这可能需要相当长的时间。

于 2013-05-18T01:15:57.687 回答
5

我们做的事情类似于 saravan 对电子邮件的建议,并怀疑它会适用于 SMS。

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

一些不在我们原始设计中的提示要牢记:

  1. 有办法手动停止所有发送(请参阅下一个提示)

  2. 以用户友好的方式终止特定消息。如果您的代码(或用户)不小心发送了五次相同的内容,您需要一种快速中止它的方法。

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

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

高温下,

-克里斯C。

于 2013-05-15T15:27:00.810 回答
3

可能是缓冲区值已满,请检查并在 web-config 文件中将其设置为最大值

于 2013-05-17T04:27:38.447 回答
3

检查您的 StreamWriter 是否正在处理

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

}
于 2013-05-14T08:56:47.653 回答
2

也许您的网络请求太快了:尝试减慢它们以排除时间问题,例如添加睡眠:

   System.Threading.Thread.Sleep(1000);

1000ms = 1 sec 只是一个提示,您应该尝试不同的值来查看是否有变化

于 2013-05-17T13:36:33.967 回答