我有一个从Android移动应用程序调用的Web服务.asmx。它会向android应用程序返回一个随机数,并使用短信发送相同的号码。
我的问题是,有时Web服务在同一时间执行多次并返回相同的随机数。因此短信在一次请求中被发送多次。
我有两个文件,一个是我从我的应用程序getRandomNumber.asmx调用的文件,第二个是getRandomNumber.cs生成数字的文件,保存到数据库并通过短信发送。
所以我在两个文件中都放了一个日志文件,然后等待副本显示。
这是我用来跟踪此问题的日志文件:
时间:2014/05/24 06:41:46 - 用户:610410 - 随机:进入IN
时间:2014/05/24 06:41:46 - 用户:610410 - 随机:进入IN
时间:2014/05/24 06:41:46 - 用户:610410 - 随机:进入IN
时间:2014/05/24 06:41:46 - 用户:610410 - 随机:进入IN
时间:2014/05/24 06:41:49 - 用户:610410 - 随机:853967
时间:2014/05/24 06:41:49 - 用户:610410 - 随机:853967
时间:2014/05/24 06:41:49 - 用户:610410 - 随机:853967
时间:2014/05/24 06:41:49 - 用户:610410 - 随机:853967
原因是什么以及如何解决它。
更新:已添加代码
getRandomNumber.asmx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Web.Script.Serialization;
using OracleDataAccessLayer;
namespace MobileWebServices
{
[WebService(Namespace = "http://www.example.com")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class getRandomNumber : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public string sendRandomNumber(int UserNumber)
{
Logger.logError("Time: " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " - user: " + UserNumber + " - random: Going IN");
return Newtonsoft.Json.JsonConvert.SerializeObject(new getRandomNumber().sendRandomNumber(UserNumber));
}
}
}
getRandomNumber.cs
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Text;
using System.IO;
namespace OracleDataAccessLayer
{
public class getRandomNumber : OracleDataAccessLayer.MobileDataAccess.OracleCommandLibrary
{
string sql = "";
public getRandomNumber() { }
string GeneratePasscode(int PasscodeLength)
{
string _allowedChars = "123456789";
Random randNum = new Random();
char[] chars = new char[PasscodeLength];
int allowedCharCount = _allowedChars.Length;
for (int i = 0; i < PasscodeLength; i++)
{
chars[i] = _allowedChars[(int)((_allowedChars.Length) * randNum.NextDouble())];
}
return new string(chars).PadRight(PasscodeLength, '0').ToString();
}
public string sendRandomNumber(int parUserNumber)
{
string random = "0";
string mobile="";
try
{
string randomNum = GeneratePasscode(6);
Logger.logError("Time: " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " - user: " + parUserNumber + " - random: " + randomNum);
//select the mobile number and the language
sql = "SELECT C.COUNTRY_LANG, MOBILE " +
"FROM COUNTRY_MASTER_TABLE C " +
"JOIN USER_REG_MASTER U ON " +
"C.COUNTRY_CODE = U.NATIONALITY_NO " +
"WHERE U.UNO = " + parUserNumber;
DataTable lang = Retrievedata(sql);
if (lang.Rows.Count > 0)
{
sql = "INSERT INTO SMS_SEND " +
"(SMS_ID, USER_NUMBER, SMS_DATE, RANDOM, DEVICE_TYPE) VALUES " +
"(SEQ_RANDOM.NEXTVAL, " + parUSERNumber + ", SYSDATE, " + randomNum + ", 1)";
if (ExecuteTransactions(sql) > 0)
{
mobile = lang.Rows[0].ItemArray[1].ToString();
// check the lang Arabic, Non Arabic
// if arabic convert to hex
if (lang.Rows[0].ItemArray[0].ToString() == "A")
{
messageOrg = "الرجاء استخدام الرمز " + randomNum;
Byte[] stringBytes = System.Text.Encoding.UTF8.GetBytes(messageOrg);
StringBuilder sbBytes = new StringBuilder(stringBytes.Length * 2);
foreach (byte bb in stringBytes)
{
sbBytes.AppendFormat("%{0:X2}", bb);
}
message = sbBytes.ToString();
messageHex = message;
}
else
{
// If english do nothing
messageOrg = "Please use this code: " + randomNum;
message = "Please use this code: " + randomNum;
}
// add the message and mobile number to SMS service provider URL and create HttpWebRequest
string url = "http://www.example.com/Send.aspx?MOBILENO=" + mobile + "&MESSAGE=" + message + "&rest of prams";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
// execute request and get response back
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
smsSequence = reader.ReadToEnd();
reader.Close();
dataStream.Close();
}
// check if success get the response and check id number and insert into SMS_SENTBOX for logging
int success = 0;
if (smsSequence.Substring(0, 3) == "+OK")
//if (Int32.TryParse(smsSequence.Substring(7, smsSequence.Length - 7), out success))
{
random = randomNum;
sql = "INSERT INTO SMS_SENTBOX " +
"(SMS_SENT_SEQUENCE, USER_NUMBER, EVENT_DATE, EVENT_TIME, USER_MOBILE, EVENT_TYPE, SENT_DATE, SMS_TEXT, SMS_TEXT_DUMP)" +
"VALUES " +
"(1, " + parUserNumber + ", SYSDATE, TO_CHAR(SYSDATE, 'HHMI'), " + mobile + ", 'random', SYSDATE, '" + messageOrg + "', '" + messageHex + "')";
try
{
ExecuteTransactions(sql);
}
catch (Exception e)
{
}
}
}
}
}
catch (Exception e)
{
Logger.logError(e.ToString() + "\n");
throw e;
}
return random;
/**/
}
}
}
三江源
答案 0 :(得分:0)
根据您的描述,我不太清楚您是否有一个问题(多次生成相同的随机数)或两个问题(多次发送相同的随机数和请求)。
无论如何,有关Random() constructor的Microsoft文档中描述了您的问题的根源:
默认种子值是从系统时钟派生的,并且是有限的 解析度。结果,创建了不同的Random对象 通过调用默认构造函数来关闭连续 相同的默认种子值,因此,将产生相同的 随机数集。
要修复它,请创建一个Random
的静态实例:
static Random random = new Random();
....
string GeneratePasscode(int PasscodeLength)
{
string _allowedChars = "123456789";
char[] chars = new char[PasscodeLength];
int allowedCharCount = _allowedChars.Length;
for (int i = 0; i < PasscodeLength; i++)
{
chars[i] = _allowedChars[(int)((_allowedChars.Length) * random.NextDouble())];
}
return new string(chars).PadRight(PasscodeLength, '0').ToString();
}