流水号的获取在单机版的程序中只需要简单的递增就可以解决。但是在分布式系统中存在多个客户端同时请求同一个流水号的问题,如果处理不好容易导致多个客户端获得同一个流水号。
解决方案一
在Oracle数据库中有专门的序列管理sequence,具体的介绍在网上可以找到很多。但是在实际使用中存在很多的问题:
1、如果有很多个不同的序列,并且在需要根据时间变化(每天0点重置)时处理起来很麻烦。
2、随时间增加数据库中的序列越来越多。
3、在首次创建一个序列的时候需要激活后才能正常使用。
所以果断放弃了这个方案。
解决方案二
大体的思路:在数据库中专门建一个表存储各类的序列,在服务器端创建一个服务专门提供各类序列当前的流水号。客户端通过这个服务来获取序列,不能直接去数据库中查
第1步:在数据库中专门创建一个新的表用来存储这些序列。表结构如下:
1、FLAG(标志码 主键):代表序列的标志
2、Sequence(当前的流水号):默认为0
3、UpdateTime(更新时间):根据自己的需要来创建
第2步:先创建一些接口
1、数据服务的接口
class="code_img_closed" src="/Upload/Images/2014112111/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('ca58b687-b8cc-434b-87aa-411b1d6535b8',event)" src="/Upload/Images/2014112111/2B1B950FA3DF188F.gif" alt="" />1 public interface IDataOperator 2 { 3 int ExecuteNonQuery(List<string> list); 4 int ExecuteNonQuery(string strSql); 5 int ExecuteNonQuery(List<string> list, ref string strError); 6 int ExecuteNonQuery(string strSql, ref string strError); 7 T ExecuteScalar<T>(string strSql); 8 T ExecuteScalar<T>(string strSql, ref string strError); 9 DataSet GetDataSet(string strSql); 10 DataSet GetDataSet(string strSql, ref string strError); 11 DataTable GetDataTable(string strSql); 12 DataTable GetDataTable(string strSql, ref string strError); 13 }View Code
2、流水号的接口
1 public interface ISequence 2 { 3 int GetNext(string strFlag); 4 }View Code
第3步:在服务器端创建一个服务,这个服务有两个功能。我这边客户端和服务端的通信用的是Remoting技术。这里就不展示相关的代码了。
1、做客户端的数据中转,直接和数据库服务器之间通信,
1 public class SqlServer : MarshalByRefObject,IDataOperator 2 { 3 #region 私有字段 4 private string strConn; 5 #endregion 6 /// <summary> 7 /// 构造器 8 /// </summary> 9 public SqlServer () 10 { 11 strConn = string.Format(@"User ID={0};Password={1};Data Source={2};Pooling=true;Min Pool Size=0;Max Pool Size={3};", 12 “”, 13 “”, 14 “” 15 “”; 16 17 } 18 /// <summary> 19 /// 打开数据库连接 20 /// </summary> 21 /// <param name="strError">返回错误信息</param> 22 /// <returns></returns> 23 public bool OpenTest(ref string strError) 24 { 25 bool blResult = false; 26 try 27 { 28 using (SqlConnection conn = new SqlConnection(strConn)) 29 { 30 conn.Open(); 31 conn.Close(); 32 } 33 blResult = true; 34 } 35 catch(Exception ex) 36 { 37 strError = ex.Message; 38 } 39 return blResult; 40 } 41 /// <summary> 42 /// 执行一个SQL语句集合返回操作成功数 43 /// </summary> 44 /// <param name="strsql"></param> 45 /// <param name="parameter"></param> 46 /// <returns></returns> 47 public int ExecuteNonQuery(List<string> list, ref string strError) 48 { 49 int intResult = 0; 50 int i = 0; 51 if (list.Count > 0) 52 { 53 try 54 { 55 using (SqlConnection conn = new SqlConnection(strConn)) 56 { 57 58 conn.Open(); 59 SqlTransaction tran = conn.BeginTransaction(); 60 61 try 62 { 63 using (SqlCommand cmd = conn.CreateCommand()) 64 { 65 cmd.Transaction = tran; 66 for (i = 0; i < list.Count; i++) 67 { 68 cmd.CommandText = list[i].Trim(); 69 intResult+= cmd.ExecuteNonQuery(); 70 } 71 tran.Commit(); 72 } 73 74 } 75 catch (Exception ex) 76 { 77 try 78 { 79 intResult = -1; 80 tran.Rollback(); 81 82 strError = 83 string.Format("{0}个操作回滚成功!{1}\r\n ErrSQL:\r\n {2}", 84 i, ex.Message, list[i]); 85 } 86 catch(Exception ex2) 87 { 88 intResult = -2; 89 strError = 90 string.Format("{0}个操作回滚失败!{1}\r\n ErrSQL:\r\n {2}", 91 i, ex2.Message, list[i]); 92 } 93 } 94 finally 95 { 96 conn.Close(); 97 } 98 } 99 } 100 catch (SqlException ex) 101 { 102 103 strError = ex.Message; 104 } 105 106 } 107 else 108 { 109 strError = string.Format("ExecuteNonQuery(List<string> list):未传入需要执行的SQL语句"); 110 } 111 return intResult; 112 113 } 114 /// <summary> 115 /// 执行一个SQL语句集合返回操作成功数 116 /// </summary> 117 /// <param name="strsql"></param> 118 /// <param name="parameter"></param> 119 /// <returns></returns> 120 public int ExecuteNonQuery(List<string> list) 121 { 122 int intResult = 0; 123 int i = 0; 124 if (list.Count > 0) 125 { 126 using (SqlConnection conn = new SqlConnection(strConn)) 127 { 128 conn.Open(); 129 SqlTransaction tran = conn.BeginTransaction(); 130 using (SqlCommand cmd = conn.CreateCommand()) 131 { 132 try 133 { 134 cmd.Transaction = tran; 135 for (i = 0; i < list.Count; i++) 136 { 137 cmd.CommandText = list[i].Trim(); 138 intResult += cmd.ExecuteNonQuery(); 139 } 140 tran.Commit(); 141 } 142 catch (Exception ex) 143 { 144 try 145 { 146 intResult = -1; 147 tran.Rollback(); 148 PubLibrary.WriteTxt( 149 string.Format("{0}个操作回滚成功!{1}\r\n ErrSQL:\r\n {2}", 150 i, ex.Message, list[i])); 151 } 152 catch (Exception ex2) 153 { 154 intResult = -2; 155 PubLibrary.WriteTxt( 156 string.Format("{0}个操作回滚失败!{1}\r\n ErrSQL:\r\n {2}", 157 i, ex2.Message, list[i])); 158 } 159 } 160 finally 161 { 162 conn.Close(); 163 } 164 165 } 166 167 } 168 } 169 else 170 { 171 PubLibrary.WriteTxt("ExecuteNonQuery(List<string> list):未传入需要执行的SQL语句"); 172 //throw new SystemException(string.Format("ExecuteNonQuery(List<string> list):未传入需要执行的SQL语句")); 173 } 174 return intResult; 175 } 176 /// <summary> 177 /// 返回操作成功数 178 /// </summary> 179 /// <param name="strSql"></param> 180 /// <returns></returns> 181 public int ExecuteNonQuery(string strSql) 182 { 183 int intResult = 0; 184 try 185 { 186 using (SqlConnection conn = new SqlConnection(strConn)) 187 { 188 conn.Open(); 189 using (SqlCommand cmd = conn.CreateCommand()) 190 { 191 cmd.CommandText = strSql; 192 193 intResult = cmd.ExecuteNonQuery(); 194 } 195 conn.Close(); 196 } 197 } 198 catch (Exception ex) 199 { 200 PubLibrary.WriteTxt(ex.Message); 201 } 202 finally 203 { 204 //conn.Close(); 205 } 206 207 return intResult; 208 } 209 /// <summary> 210 /// 返回操作成功数 211 /// </summary> 212 /// <param name="strSql"></param> 213 /// <returns></returns> 214 public int ExecuteNonQuery(string strSql, ref string strError) 215 { 216 int intResult =0; 217 try 218 { 219 using (SqlConnection conn = new SqlConnection(strConn)) 220 { 221 conn.Open(); 222 using (SqlCommand cmd = conn.CreateCommand()) 223 { 224 cmd.CommandText = strSql; 225 226 intResult = cmd.ExecuteNonQuery(); 227 } 228 conn.Close(); 229 } 230 } 231 catch (Exception ex) 232 { 233 strError = ex.Message; 234 } 235 finally 236 { 237 238 239 } 240 241 return intResult; 242 243 } 244 /// <summary> 245 /// 返回纪录集第一行第一列的数据 246 /// </summary> 247 /// <typeparam name="T"></typeparam> 248 /// <param name="strSql"></param> 249 /// <returns></returns> 250 public T ExecuteScalar<T>(string strSql) 251 { 252 T temp = default(T); 253 try 254 { 255 using (SqlConnection conn = new SqlConnection(strConn)) 256 { 257 conn.Open(); 258 using (SqlCommand cmd = conn.CreateCommand()) 259 { 260 261 cmd.CommandText = strSql; 262 263 object o = cmd.ExecuteScalar(); 264 if (o != null && o != DBNull.Value) 265 { 266 temp = (T)Convert.ChangeType(o, typeof(T)); 267 } 268 } 269 conn.Close(); 270 } 271 272 273 } 274 catch (SqlException ex) 275 { 276 PubLibrary.WriteTxt(ex.Message); 277 } 278 finally 279 { 280 281 } 282 return temp; 283 284 } 285 286 /// <summary> 287 /// 返回纪录集第一行第一列的数据 288 /// </summary> 289 /// <typeparam name="T"></typeparam> 290 /// <param name="strSql"></param> 291 /// <param name="strError"></param> 292 /// <returns></returns> 293 public T ExecuteScalar<T>(string strSql, ref string strError) 294 { 295 296 T temp = default(T); 297 try 298 { 299 using (SqlConnection conn = new SqlConnection(strConn)) 300 { 301 conn.Open(); 302 using (SqlCommand cmd = conn.CreateCommand()) 303 { 304 305 cmd.CommandText = strSql; 306 307 object o = cmd.ExecuteScalar(); 308 if (o != null && o != DBNull.Value) 309 { 310 temp = (T)Convert.ChangeType(o, typeof(T)); 311 } 312 } 313 conn.Close(); 314 } 315 } 316 catch (SqlException ex) 317 { 318 strError = ex.Message; 319 } 320 finally 321 { 322 323 } 324 return temp; 325 } 326 /// <summary> 327 /// 获取数据集 328 /// </summary> 329 /// <param name="strSql"></param> 330 /// <returns></returns> 331 public DataSet GetDataSet(string strSql) 332 { 333 334 DataSet ds = new DataSet(); 335 try 336 { 337 using (SqlConnection conn = new SqlConnection(strConn)) 338 { 339 conn.Open(); 340 using (SqlCommand cmd = conn.CreateCommand()) 341 { 342 cmd.CommandText = strSql; 343 SqlDataAdapter adapter = new SqlDataAdapter(cmd); 344 adapter.Fill(ds); 345 } 346 conn.Close(); 347 } 348 } 349 catch (Exception ex) 350 { 351 PubLibrary.WriteTxt(ex.Message); 352 } 353 finally 354 { 355 356 } 357 return ds; 358 } 359 360 /// <summary> 361 /// 获取数据集 362 /// </summary> 363 /// <param name="strSql"></param> 364 /// <param name="strError"></param> 365 /// <returns></returns> 366 public DataSet GetDataSet(string strSql,ref string strError) 367 { 368 DataSet ds = new DataSet(); 369 try 370 { 371 using (SqlConnection conn = new SqlConnection(strConn)) 372 { 373 conn.Open(); 374 using (SqlCommand cmd = conn.CreateCommand()) 375 { 376 cmd.CommandText = strSql; 377 SqlDataAdapter adapter = new SqlDataAdapter(cmd); 378 adapter.Fill(ds); 379 } 380 conn.Close(); 381 } 382 } 383 catch (Exception ex) 384 { 385 strError = ex.Message; 386 } 387 388 return ds; 389 } 390 391 /// <summary> 392 /// 获取第一张数据表 393 /// </summary> 394 /// <param name="strSql"></param> 395 /// <returns></returns> 396 public DataTable GetDataTable(string strSql) 397 { 398 DataTable dt = new DataTable(); 399 try 400 { 401 using (SqlConnection conn = new SqlConnection(strConn)) 402 { 403 conn.Open(); 404 using (SqlCommand cmd = conn.CreateCommand()) 405 { 406 cmd.CommandText = strSql; 407 408 SqlDataAdapter adapter = new SqlDataAdapter(cmd); 409 DataSet ds = new DataSet(); 410 adapter.Fill(ds); 411 if (ds != null && ds.Tables.Count > 0) 412 { 413 dt = ds.Tables[0]; 414 } 415 } 416 conn.Close(); 417 } 418 419 } 420 catch (Exception ex) 421 { 422 PubLibrary.WriteTxt(ex.Message); 423 } 424 425 426 return dt; 427 } 428 429 /// <summary> 430 /// 获取第一张数据表 431 /// </summary> 432 /// <param name="strSql"></param> 433 /// <param name="strError"></param> 434 /// <returns></returns> 435 public DataTable GetDataTable(string strSql,ref string strError) 436 { 437 DataTable dt = new DataTable(); 438 try 439 { 440 using (SqlConnection conn = new SqlConnection(strConn)) 441 { 442 conn.Open(); 443 using (SqlCommand cmd = conn.CreateCommand()) 444 { 445 cmd.CommandText = strSql; 446 SqlDataAdapter adapter = new SqlDataAdapter(cmd); 447 DataSet ds = new DataSet(); 448 adapter.Fill(ds); 449 if (ds != null && ds.Tables.Count > 0) 450 { 451 dt = ds.Tables[0]; 452 } 453 } 454 conn.Close(); 455 } 456 } 457 catch (Exception ex) 458 { 459 strError = ex.Message; 460 } 461 finally 462 { 463 464 } 465 return dt; 466 } 467 468 469 }View Code
2、创建流水号的类, “_nextTen += 10;//如果流水号获取很频繁这个值可以设大一点”这里相当于一个缓存机制,以减少对数据库的访问量。可以根据实际需求来增大或减少。这里要注意一点如果服务有重启会有部分流水号丢失。如果是对流水号的连续性要求高的最好设置为1,但是这样对数据库的访问量会非常大。会导致获取流水号的平均时间增加,我的测试(普通台式电脑做服务器同时有30个进程在获取同一个流水号)是在10个缓存的情况下平均时间是10ms以内。
1 public class BCSequence 2 { 3 private string _strFlag; 4 IDataOperator dataOperator; 5 public BCSequence(IDataOperator dataOperator) 6 { 7 this.dataOperator = dataOperator; 8 } 9 public BCSequence(string strFlag, int intSequence, IDataOperator dataOperator) 10 { 11 this._strFlag = strFlag; 12 this._intSequence = intSequence; 13 this._nextTen = intSequence; 14 this.dataOperator = dataOperator; 15 16 } 17 18 public string StrFlag 19 { 20 get { return _strFlag; } 21 set { _strFlag = value; } 22 } 23 int _intSequence; 24 int _nextTen 25 { 26 get; 27 set; 28 } 29 30 31 /// <summary> 32 /// 流水号保存不了则返回-1 33 /// </summary> 34 public int Next 35 { 36 get 37 { 38 if (_intSequence >= _nextTen) 39 { 40 _nextTen += 10;//如果流水号获取很频繁这个值可以设大一点 41 if (SaveInfo() <= 0) 42 { 43 _nextTen -= 10;//保存失败必须将值变回10否则会出现重码的情况 44 return -1; 45 46 } 47 } 48 _intSequence++; 49 return _intSequence; 50 } 51 } 52 public int SaveInfo() 53 { 54 int intResult = -1; 55 try 56 { 57 string strSql = string.Format(@"Select Count(*) from HT_Barcode_Sequence where Flag='{0}'", StrFlag); 58 59 intResult = dataOperator.ExecuteScalar<int>(strSql); 60 if (intResult == 0) 61 { 62 strSql = 63 string.Format(@"Insert into HT_Barcode_Sequence(Flag,Sequence,Update_Time)values('{0}',{1},Now())", 64 _strFlag, _nextTen); 65 } 66 else 67 { 68 strSql = 69 string.Format(@"Update HT_Barcode_Sequence set Sequence={0},Update_Time=Now() where Flag='{1}'", 70 _nextTen, _strFlag); 71 } 72 intResult = dataOperator.ExecuteNonQuery(strSql); 73 } 74 catch (Exception ex) 75 { 76 //PubLibrary.WriteTxt(ex.Message); 77 } 78 79 return intResult; 80 81 } 82 public static BCSequence CreatSeq(string strFlag, IDataOperator dataOperator) 83 { 84 BCSequence BCSeq = null; 85 try 86 { 87 //PBSSQLServer pbssql = new PBSSQLServer(); 88 string strSql = string.Format(@"Select Flag,Sequence,Update_Time from HT_Barcode_Sequence where Flag='{0}'", 89 strFlag); 90 using (DataTable dt = dataOperator.GetDataTable(strSql)) 91 { 92 if (dt != null && dt.Rows.Count > 0) 93 { 94 int intSequence = DataConvert.DbToInt(dt.Rows[0]["Sequence"]); 95 BCSeq = new BCSequence(strFlag, intSequence,dataOperator); 96 } 97 else 98 { 99 BCSeq = new BCSequence(strFlag, 0,dataOperator); 100 if (BCSeq.SaveInfo() <= 0) 101 { 102 BCSeq = null; 103 } 104 } 105 } 106 } 107 catch (Exception ex) 108 { 109 //PubLibrary.WriteTxt(ex.Message); 110 } 111 112 return BCSeq; 113 } 114 115 116 }View Code
3、管理所有的流水号,客户端要获取流水号需要依靠这个服务
1 public class BarcodeSequence:MarshalByRefObject,ISequence 2 { 3 4 public BarcodeSequence() 5 { 6 7 } 8 /// <summary> 9 /// 10 /// </summary> 11 /// <param name="strFlag"></param> 12 /// <returns>返回相应标志码的流水号,如果数据库交互出现问题得不到标志码的流水号,或创建不了标志码。则返回-2</returns> 13 public int GetNext(string strFlag) 14 { 15 BCSequence bs = Get(strFlag); 16 if (bs == null) 17 { 18 bs = Creat(strFlag); 19 //将新创建的标志码类放入队列的工作交给创建器 20 } 21 if (bs != null) 22 { 23 return bs.Next; 24 } 25 else //如果数据库交互出现问题得不到标志码的流水号,或创建不了标志码。则返回-2 26 { 27 return -2; 28 } 29 } 30 /// <summary> 31 /// 标志码生成器 32 /// </summary> 33 /// <param name="strFlag"></param> 34 /// <returns></returns> 35 public BCSequence Creat(string strFlag) 36 { 37 lock (PubLibrary.CreatObj) 38 { 39 BCSequence bs = Get(strFlag); 40 if (bs == null) 41 { 42 bs= BCSequence.CreatSeq(strFlag,new SQLServer()); 43 44 if (bs != null) 45 { 46 PubLibrary.lstSeq.Add(bs); 47 } 48 } 49 return bs; 50 } 51 52 } 53 54 /// <summary> 55 /// 获取标志码列表中对应的标志码 56 /// </summary> 57 /// <param name="strFlag">要查询的标志码</param> 58 /// <returns></returns> 59 public BCSequence Get(string strFlag) 60 { 61 BCSequence bs = null; 62 foreach (BCSequence bcbs in PubLibrary.lstSeq) 63 { 64 if (bcbs.StrFlag == strFlag) 65 { 66 67 bs = bcbs; 68 break; 69 } 70 } 71 return bs; 72 } 73 74 }View Code
还有一个静态类专门存储现在在使用的一些流水号列表等信息
1 public class PubLibrary 2 { 3 4 public static object CreatObj=new object(); 5 ///// <summary> 6 ///// 提供给服务内部的类查询数据使用的SQLServer 7 ///// </summary> 8 //public static SQLServer pbsSQL = new SQLServer(); 9 10 public static List<BCSequence> lstSeq = new List<BCSequence>(); 11 12 public static void RegistRemotingObject() 13 { 14 15 string strServicename = ""; 16 string strChannelType =""; 17 int intChannelNo =Convert.ToInt32("");; 18 string strCallType = "SingleCall"; 19 int intInitialLeaseTime = Convert.ToInt32(""); 20 int intSponsorshipTimeout =Convert.ToInt32(""); 21 int intRenewOnCallTime =Convert.ToInt32(""); 22 string strSeqServicename =""; 23 string strSeqChannelType = ""; 24 int intSeqChannelNo = Convert.ToInt32(""); 25 string strSeqInfo = ""; 26 string strSeqCallType = "SingleCall"; 27 int intSeqInitialLeaseTime = Convert.ToInt32(""); 28 int intSeqSponsorshipTimeout = Convert.ToInt32(""); 29 int intSeqRenewOnCallTime = Convert.ToInt32(""); 30 try 31 { 32 CreateRemotingObject<SQLServer>(intChannelNo, strCallType, strServicename, strChannelType, intInitialLeaseTime, intSponsorshipTimeout, intRenewOnCallTime); 33 PubLibrary.WriteTxt(string.Format("已经注册类型SQLServer {0},{1},{2},{4},{5},{6}",intChannelNo, strCallType, strServicename, strChannelType, intInitialLeaseTime, intSponsorshipTimeout, intRenewOnCallTime )); 34 35 CreateRemotingObject<BarcodeSequence>(intSeqChannelNo, strSeqCallType, strSeqServicename, strSeqChannelType, intSeqInitialLeaseTime, intSeqSponsorshipTimeout, intSeqRenewOnCallTime); 36 PubLibrary.WriteTxt(string.Format("已经注册类型BarcodeSequence {0},{1},{2},{4},{5},{6}", intSeqChannelNo, strSeqCallType, strSeqServicename, strSeqChannelType, intSeqInitialLeaseTime, intSeqSponsorshipTimeout, intSeqRenewOnCallTime)); 37 38 } 39 catch (Exception ex) 40 { 41 PubLibrary.WriteTxt(ex.Message); 42 } 43 } 44 45 /// <summary> 46 /// 清除远程对象 47 /// </summary> 48 public static void ClearRemotingObject() 49 { 50 try 51 { 52 MES.EI.RemotingOperation.UnregisterChannel(); 53 } 54 catch (Exception ex) 55 { 56 PubLibrary.WriteTxt(ex.Message); 57 } 58 } 59 60 /// <summary> 61 /// 以Append的模式往指定的文本文件写入文本信息 62 /// </summary> 63 /// <param name="Info" >信息</param> 64 public static void WriteTxt(string Info) 65 { 66 string filename = Service.StartPath + "Error_" + System.DateTime.Now.ToString("yyyyMMdd") + ".txt"; 67 68 if (filename.Substring(filename.Length - 3).ToUpper() == "TXT") 69 { 70 lock (typeof(PubLibrary)) 71 { 72 System.IO.FileStream s = System.IO.File.Open(filename, System.IO.FileMode.Append); 73 System.IO.StreamWriter w = new System.IO.StreamWriter(s); 74 w.WriteLine(System.DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + ":" + Info); 75 w.Close(); 76 } 77 } 78 else 79 { 80 throw new ApplicationException(filename + " isn't a txt file."); 81 } 82 } 83 /// <summary> 84 /// 把相关信息写入事件日志 85 /// </summary> 86 /// <param name="Info">信息</param> 87 /// <param name="type">事件类型</param> 88 public static void WriteEvent(string Info, System.Diagnostics.EventLogEntryType type) 89 { 90 Service.ServiceLog.WriteEntry(Info, type); 91 } 92 93 /// <summary> 94 /// 根据指定参数创建远程对象 95 /// </summary> 96 /// <typeparam name="T">Remoting服务的数据类型</typeparam> 97 /// <param name="Port">端口</param> 98 /// <param name="CallType">激活类型</param> 99 /// <param name="RemotingServerName">远程服务名称</param> 100 /// <param name="ChannelType">通道类型</param> 101 /// <param name="InitialLeaseTime">租约的初始时间</param> 102 /// <param name="SponsorshipTimeout">等待主办方返回租约续订时间的时间</param> 103 /// <param name="RenewOnCallTime">对象重新调用时增加的生存期</param> 104 private static void CreateRemotingObject<T>(int Port, string CallType, string RemotingServerName, string ChannelType, 105 int InitialLeaseTime, int SponsorshipTimeout, int RenewOnCallTime) 106 { 107 try 108 { 109 RemotingChannelType[] channeltypes = RemotingServerInfo.GetChannelTypeFromString(ChannelType); 110 111 if (channeltypes != null && channeltypes.Length > 0) 112 { 113 RemotingServerInfo remotinginfo = new RemotingServerInfo 114 (Port, CallType, RemotingServerName, channeltypes); 115 116 RemotingEventInfo eventinfo = new RemotingEventInfo 117 (HTPBSService.ServiceLog, System.Diagnostics.EventLogEntryType.Information, 118 InitialLeaseTime, SponsorshipTimeout, RenewOnCallTime); 119 120 RemotingOperation.CreateRemotingServerFullDeserialization<T>(remotinginfo, eventinfo); 121 } 122 } 123 catch (System.Exception ex) 124 { 125 PubLibrary.WriteTxt( 126 string.Format("{0}:服务不能启动,因为{1} {2}", DateTime.Now.ToString(), ex.Message, ex.StackTrace)); 127 } 128 } 129 }View Code
第4步:创建客户端
1 public class SqlSequence :IClientSequence 2 { 3 ISequence se; 4 private string strMachineNo; 5 private int intChannelNo; 6 private string strServiceName; 7 /// <summary> 8 /// 构造器 9 /// </summary> 10 /// <param name="MachineNo">服务器电脑名</param> 11 /// <param name="ChannelNo">服务端口</param> 12 /// <param name="ServiceName">服务名</param> 13 public SqlSequence(string MachineNo, int ChannelNo, string ServiceName) 14 { 15 this.strMachineNo = MachineNo; 16 this.intChannelNo = ChannelNo; 17 this.strServiceName = ServiceName; 18 } 19 /// <summary> 20 /// 打开到远程服务器的通道 21 /// </summary> 22 /// <returns></returns> 23 public bool OpenRemoting() 24 { 25 try 26 { 27 RemotingClientInfo clientinfo; 28 clientinfo = new RemotingClientInfo(strMachineNo, 29 intChannelNo, 30 strServiceName, 31 RemotingChannelType.Tcp); 32 GetRemotingVoucher(ref clientinfo); 33 se = RemotingOperation.CreateRemotingClient<ISequence>(clientinfo); 34 35 return true; 36 } 37 catch (Exception ex) 38 { 39 //PubLibrary.WriteTxt(ex.Message); 40 return false; 41 } 42 } 43 44 45 public bool GetNext(string strFlag, out int index, ref string strError) 46 { 47 bool blResult = false; 48 index = -1; 49 try 50 { 51 index = se.GetNext(strFlag); 52 if (index != -1) 53 { 54 blResult = true; 55 } 56 else 57 { 58 strError = "服务端出现错误无法获取流水号"; 59 } 60 } 61 catch (Exception ex) 62 { 63 64 if (ex.Message.Contains("由于目标计算机积极拒绝")) 65 { 66 67 string strName = System.Net.Dns.GetHostEntry(ex.Message.Split(' ')[1].Split(':')[0]).HostName.Split('.')[0]; 68 strError = "由于服务器[" + strName + "]上的喷码服务已停止\r\n\r\n暂时无法喷印,请联系管理员开启喷码服务"; 69 } 70 else 71 { 72 strError = ex.Message; 73 } 74 75 } 76 return blResult; 77 } 78 /// <summary> 79 /// 指定远程连接时客户端信息 80 /// </summary> 81 /// <param name="clientinfo"></param> 82 private void GetRemotingVoucher(ref RemotingClientInfo clientinfo) 83 { 84 //clientinfo.IsTrusty = true; 85 //if (!clientinfo.IsTrusty) 86 //{ 87 clientinfo.IsTrusty = false; 88 clientinfo.UserName = "BMES"; 89 clientinfo.Password = "Battery123"; 90 clientinfo.Domain = ""; 91 //} 92 } 93 94 /// <summary> 95 /// 关闭远程通道 96 /// </summary> 97 public void CloseRemoting() 98 { 99 100 RemotingOperation.UnregisterChannel(); 101 102 se = null; 103 } 104 }View Code
第5步:测试
1 SqlSequence BSeq = new SqlSequence(strSeqMachineName, intSeqChannel, strSeqServerName); 2 3 string strFlag =""; 4 5 int index = 0; 6 7 if( BSeq.GetNext(strFlag, out index, ref strError)) 8 9 { 10 11 //成功 12 13 } 14 15 else 16 17 { 18 19 //失败 20 21 }View Code