为大量用户发送短信

Any*_*are 4 c# asp.net performance sms httpwebrequest

我想发送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;
            }

        }
Run Code Online (Sandbox Code Playgroud)

在特定数量的用户(例如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) 
Run Code Online (Sandbox Code Playgroud)

Sar*_*nan 6

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

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

这是最广泛建议的方法.

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


Jus*_*yde 6

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

我有一个缓存/临时存储/表在哪里批量大目的地(高达1,000,000)在某些情况下和一个调度器(基于定时器)发送的500每隔几秒钟,每批次(通过调用脚本重复),直到消息被发送.像魅力一样工作!

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

处理:

你需要三件物品

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

A.发送短信请求到达

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

b. The Destinations (as a comma delimited list). We'll assume 10,000 destinations
Run Code Online (Sandbox Code Playgroud)

B.将目的地分成500(您希望的任何大小),并在每个INBOX行/记录中记录500个目的地以及消息和SenderID. 注意:如果通过循环计算500次(10,000次循环),脚本可能会超时.我国的GSM号码是13位数.所以我做了一个长度为500(13 + 1)的循环子字符串,每批获得500个目的地(20个循环).*

C.调用发送短信的脚本.发送前500并将邮件标记为已发送.您可以添加发送时间.启动计划程序

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


J. *_*ton 5

我们做了类似于saravan建议的电子邮件消息,并怀疑它将工作SMS.

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

我们的原始设计中没有一些提示要记住:

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

  2. 以用户友好的方式终止特定邮件.如果您的代码(或用户)意外地发送了相同的东西五次,那么您需要一种方法来快速中止它.

  3. 对两个数字(上面的x和y)使用配置文件,这样您无需重新部署即可进行调整.我认为y延迟是50毫秒.

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

HTH,

-Chris C.


Jon*_*ech 5

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

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

  <system.web>
    <!-- 600 seconds = 10 minute timeout --->
    <httpRuntime executionTimeout="600"/>
  </system.web>
Run Code Online (Sandbox Code Playgroud)

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

请参阅Parallel.ForEach以获取线程化此过程的简单方法.

Msdn - httpRuntime文档


Chr*_*son 5

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