流水號獲取的解決方案


  流水號的獲取在單機版的程序中只需要簡單的遞增就可以解決。但是在分布式系統中存在多個客戶端同時請求同一個流水號的問題,如果處理不好容易導致多個客戶端獲得同一個流水號。

解決方案一

  在Oracle數據庫中有專門的序列管理sequence,具體的介紹在網上可以找到很多。但是在實際使用中存在很多的問題:

    1、如果有很多個不同的序列,並且在需要根據時間變化(每天0點重置)時處理起來很麻煩。

    2、隨時間增加數據庫中的序列越來越多。

    3、在首次創建一個序列的時候需要激活后才能正常使用。

  所以果斷放棄了這個方案。

解決方案二

  大體的思路:在數據庫中專門建一個表存儲各類的序列,在服務器端創建一個服務專門提供各類序列當前的流水號。客戶端通過這個服務來獲取序列,不能直接去數據庫中查

  第1步:在數據庫中專門創建一個新的表用來存儲這些序列。表結構如下:

    1、FLAG(標志碼 主鍵):代表序列的標志

    2、Sequence(當前的流水號):默認為0

    3、UpdateTime(更新時間):根據自己的需要來創建

  第2步:先創建一些接口

    1、數據服務的接口      

 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

 

  

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM