.NET疯狂架构经验分享系列之(七)WCF支持(转)
本文只做入門參考用,WCF服務(wù)器端注意事項
1:WCF服務(wù)器端配置文件如何寫很關(guān)鍵、例如多個服務(wù)怎么一同發(fā)布?
2:如何用最簡單的程序,把WCF服務(wù)器發(fā)布好?
3:配置文件如何配置,客戶端才能正常引用已發(fā)布的服務(wù)?
其實這3個問題,是服務(wù)器端編寫程序的核心關(guān)鍵問題,這解決了,就算是好入門了,接著可以深入某個問題了。
?
工程的效果圖如下:
?
以下程序是啟動WCF服務(wù)用的程序參考:
?
????????????//?讀取配置文件????????????Configuration?configuration?=?ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
????????????ServiceModelSectionGroup?serviceModelSectionGroup?=?(ServiceModelSectionGroup)configuration.GetSectionGroup("system.serviceModel");
????????????//?開啟每個服務(wù)
????????????foreach?(ServiceElement?serviceElement?in?serviceModelSectionGroup.Services.Services)
????????????{
????????????????var?serviceHost?=?new?ServiceHost(Assembly.Load("DotNet.Service").GetType(serviceElement.Name),?serviceElement.Endpoints[0].Address);
????????????????serviceHost.Opened?+=?delegate?{?Console.WriteLine("{0}",?serviceHost.BaseAddresses[0]);?};
????????????????serviceHost.Open();
????????????}
?
?
以下文件為 WCF的服務(wù)器端配置文件:
<?xml?version="1.0"?encoding="utf-8"?><configuration>
??<system.serviceModel>
????<services>
??????<service?name="DotNet.Service.BusinessCardService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/BusinessCardService/"?binding="basicHttpBinding"?contract="DotNet.IService.IBusinessCardService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.ExceptionService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/ExceptionService/"?binding="basicHttpBinding"?contract="DotNet.IService.IExceptionService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.FileService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/FileService/"?binding="basicHttpBinding"?contract="DotNet.IService.IFileService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.FolderService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/FolderService/"?binding="basicHttpBinding"?contract="DotNet.IService.IFolderService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.ItemDetailsService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/ItemDetailsService/"?binding="basicHttpBinding"?contract="DotNet.IService.IItemDetailsService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.ItemsService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/ItemsService/"?binding="basicHttpBinding"?contract="DotNet.IService.IItemsService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.LoginService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/LoginService/"?binding="basicHttpBinding"?contract="DotNet.IService.ILoginService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.LogService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/LogService/"?binding="basicHttpBinding"?contract="DotNet.IService.ILogService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.MessageService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/MessageService/"?binding="basicHttpBinding"?contract="DotNet.IService.IMessageService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.ModuleService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/ModuleService/"?binding="basicHttpBinding"?contract="DotNet.IService.IModuleService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.OrganizeService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/OrganizeService/"?binding="basicHttpBinding"?contract="DotNet.IService.IOrganizeService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.ParameterService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/ParameterService/"?binding="basicHttpBinding"?contract="DotNet.IService.IParameterService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.PermissionAdminService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/PermissionAdminService/"?binding="basicHttpBinding"?contract="DotNet.IService.IPermissionAdminService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.PermissionService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/PermissionService/"?binding="basicHttpBinding"?contract="DotNet.IService.IPermissionService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.RoleService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/RoleService/"?binding="basicHttpBinding"?contract="DotNet.IService.IRoleService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.SequenceService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/SequenceService/"?binding="basicHttpBinding"?contract="DotNet.IService.ISequenceService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.StaffService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/StaffService/"?binding="basicHttpBinding"?contract="DotNet.IService.IStaffService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.UserService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/UserService/"?binding="basicHttpBinding"?contract="DotNet.IService.IUserService">
????????</endpoint>
??????</service>
??????<service?name="DotNet.Service.WorkReportService"?behaviorConfiguration="Internet">
????????<endpoint?address="http://localhost:8888/DotNet.Service/WorkReportService/"?binding="basicHttpBinding"?contract="DotNet.IService.IWorkReportService">
????????</endpoint>
??????</service>
????</services>
????<behaviors>
??????<serviceBehaviors>
????????<behavior?name="Internet">
??????????<serviceMetadata?httpGetEnabled="true"?/>
????????</behavior>
??????</serviceBehaviors>
????</behaviors>
??</system.serviceModel>
</configuration>
?
?
接口文件參考:
//------------------------------------------------------------//?All?Rights?Reserved?,?Copyright?(C)?2010?,?Jirisoft?,?Ltd.?
//------------------------------------------------------------
using?System.Data;
using?System.ServiceModel;
namespace?DotNet.IService
{
????using?DotNet.Utilities;
????///?<summary>
????///?ILoginService
????///?
????///?修改紀(jì)錄
????///?
????///????????2009.04.15?版本:1.0?JiRiGaLa?添加接口定義。
????///????????
????///?版本:1.0
????///
????///?<author>
????///????????<name>JiRiGaLa</name>
????///????????<date>2009.04.15</date>
????///?</author>?
????///?</summary>
????[ServiceContract]
????public?interface?ILoginService
????{
????????///?<summary>
????????///?獲得登錄用戶列表
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>數(shù)據(jù)表</returns>
????????[OperationContract]
????????DataTable?GetUserDT(BaseUserInfo?userInfo);
????????///?<summary>
????????///?獲得內(nèi)部員工列表
????????///?</summary>
????????///?<param?name="userInfo"></param>
????????///?<returns></returns>
????????[OperationContract]
????????DataTable?GetStaffDT(BaseUserInfo?userInfo);
????????///?<summary>
????????///?按唯一識別碼登錄
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="suid">唯一識別碼</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>用戶實體</returns>
????????[OperationContract]
????????BaseUserInfo?LoginBySuid(BaseUserInfo?userInfo,?string?suid,?out?string?statusCode,?out?string?statusMessage);
????????///?<summary>
????????///?按用戶名登錄
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="userName">用戶名</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>用戶實體</returns>
????????[OperationContract]
????????BaseUserInfo?LoginByUserName(BaseUserInfo?userInfo,?string?userName,?out?string?statusCode,?out?string?statusMessage);
????????///?<summary>
????????///?登錄
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="userName">用戶名</param>
????????///?<param?name="password">密碼</param>
????????///?<param?name="ipAddress">IP地址</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>登錄實體類</returns>
????????[OperationContract]
????????BaseUserInfo?UserLogin(BaseUserInfo?userInfo,?string?userName,?string?password,?out?string?statusCode,?out?string?statusMessage);
????????///?<summary>
????????///?操作員退出應(yīng)用程序
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????[OperationContract]
????????void?OnExit(BaseUserInfo?userInfo);
????????///?<summary>
????????///?檢查在線狀態(tài)(服務(wù)器專用)
????????///?</summary>
????????///?<returns>離線人數(shù)</returns>
????????[OperationContract]
????????int?ServerCheckOnLine();
????????///?<summary>
????????///?檢查在線狀態(tài)
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>離線人數(shù)</returns>
????????[OperationContract]
????????int?CheckOnLine(BaseUserInfo?userInfo);
????????///?<summary>
????????///?獲取在線用戶列表
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>數(shù)據(jù)表</returns>
????????[OperationContract]
????????DataTable?GetOnLineState(BaseUserInfo?userInfo);
????????///?<summary>
????????///?設(shè)置密碼
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="userIds">被設(shè)置的用戶主鍵</param>
????????///?<param?name="password">新密碼</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>影響行數(shù)</returns>
????????[OperationContract]
????????int?SetPassword(BaseUserInfo?userInfo,?string[]?userIds,?string?password,?out?string?statusCode,?out?string?statusMessage);
????????
????????///?<summary>
????????///?修改密碼
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="oldPassword">原始密碼</param>
????????///?<param?name="newPassword">新密碼</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>影響行數(shù)</returns>
????????[OperationContract]
????????int?ChangePassword(BaseUserInfo?userInfo,?string?oldPassword,?string?newPassword,?out?string?statusCode,?out?string?statusMessage);
????}
}
?
?
服務(wù)實現(xiàn)參考:
//------------------------------------------------------------//?All?Rights?Reserved?,?Copyright?(C)?2010?,?Jirisoft?,?Ltd.?
//------------------------------------------------------------
using?System;
using?System.Data;
using?System.Reflection;
namespace?DotNet.Service
{
????using?DotNet.Business;
????using?DotNet.DbUtilities;
????using?DotNet.IService;
????using?DotNet.Model;
????using?DotNet.Utilities;
????///?<summary>
????///?ILoginService
????///?
????///?修改紀(jì)錄
????///?
????///????????2009.04.15?版本:1.0?JiRiGaLa?添加接口定義。
????///????????
????///?版本:1.0
????///
????///?<author>
????///????????<name>JiRiGaLa</name>
????///????????<date>2009.04.15</date>
????///?</author>?
????///?</summary>
????public?class?LoginService?:?System.MarshalByRefObject,?ILoginService
????{
????????#region?public?void?Load()
????????///?<summary>
????????///?加載服務(wù)層
????????///?</summary>
????????public?void?Load()
????????{
????????}
????????#endregion
????????#region?public?DataTable?GetUserDT(BaseUserInfo?userInfo)?獲得用戶列表
????????///?<summary>
????????///?獲得用戶列表
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>數(shù)據(jù)表</returns>
????????public?DataTable?GetUserDT(BaseUserInfo?userInfo)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????DataTable?dataTable?=?new?DataTable(BaseStaffTable.TableName);
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????//?檢查用戶在線狀態(tài)(服務(wù)器專用)
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????userManager.CheckOnLine();
????????????????//?獲取允許登錄列表
????????????????string[]?names?=?new?string[]?{?BaseUserTable.FieldEnabled,?BaseUserTable.FieldDeleteMark};
????????????????Object[]?values?=?new?Object[]?{?1,?0};
????????????????dataTable?=?userManager.GetDT(names,?values);
????????????????BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?dataTable;
????????}
????????#endregion
????????#region?public?DataTable?GetUserDT(BaseUserInfo?userInfo)?獲得內(nèi)部職員列表
????????///?<summary>
????????///?獲得內(nèi)部職員列表
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>數(shù)據(jù)表</returns>
????????public?DataTable?GetStaffDT(BaseUserInfo?userInfo)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????DataTable?dataTable?=?new?DataTable(BaseStaffTable.TableName);
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????//?檢查用戶在線狀態(tài)(服務(wù)器專用)
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper);
????????????????userManager.CheckOnLine();
????????????????//?獲取允許登錄列表
????????????????string[]?names?=?new?string[]{BaseUserTable.FieldEnabled,?BaseUserTable.FieldDeleteMark,?BaseUserTable.FieldIsStaff};
????????????????Object[]?values?=?new?Object[]?{?1,?0,?1?};
????????????????dataTable?=?userManager.GetDT(names,?values);
????????????????BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?dataTable;
????????}
????????#endregion
????????#region?public?BaseUserInfo?LoginBySuid(BaseUserInfo?userInfo,?string?suid,?out?string?statusCode,?out?string?statusMessage)?按唯一識別碼登錄
????????///?<summary>
????????///?按唯一識別碼登錄
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="suid">唯一識別碼</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>用戶實體</returns>
????????public?BaseUserInfo?LoginBySuid(BaseUserInfo?userInfo,?string?suid,?out?string?statusCode,?out?string?statusMessage)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????BaseUserInfo?returnUserInfo?=?null;
????????????statusCode?=?string.Empty;
????????????statusMessage?=?string.Empty;
????????????
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????//?先偵測是否在線
????????????????userManager.CheckOnLine();
????????????????//?再進(jìn)行登錄
????????????????returnUserInfo?=?userManager.LoginBySuid(suid,?userInfo.IPAddress,?userInfo.MACAddress,?out?statusCode);
????????????????statusMessage?=?userManager.GetStateMessage(statusCode);
????????????????//?登錄時會自動記錄進(jìn)行日志記錄,所以不需要進(jìn)行重復(fù)日志記錄
????????????????//?BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?returnUserInfo;
????????}
????????#endregion
????????#region?public?BaseUserInfo?LoginByUserName(BaseUserInfo?userInfo,?string?userName,?out?string?statusCode,?out?string?statusMessage)?按 用戶名登錄
????????///?<summary>
????????///?按用戶名登錄
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="userName">用戶名</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>用戶實體</returns>
????????public?BaseUserInfo?LoginByUserName(BaseUserInfo?userInfo,?string?userName,?out?string?statusCode,?out?string?statusMessage)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????BaseUserInfo?returnUserInfo?=?null;
????????????statusCode?=?string.Empty;
????????????statusMessage?=?string.Empty;
????????????
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????//?先偵測是否在線
????????????????userManager.CheckOnLine();
????????????????//?再進(jìn)行登錄
????????????????returnUserInfo?=?userManager.LoginByUserName(userName,?userInfo.IPAddress,?userInfo.MACAddress,?out?statusCode);
????????????????statusMessage?=?userManager.GetStateMessage(statusCode);
????????????????//?登錄時會自動記錄進(jìn)行日志記錄,所以不需要進(jìn)行重復(fù)日志記錄
????????????????//?BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?returnUserInfo;
????????}
????????#endregion
????????#region?public?BaseUserInfo?UserLogin(BaseUserInfo?userInfo,?string?userName,?string?password,?out?string?statusCode,?out?string?statusMessage)?用 戶登錄
????????///?<summary>
????????///?用戶登錄
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="userName">用戶名</param>
????????///?<param?name="password">密碼</param>
????????///?<param?name="ipAddress">IP地址</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>用戶實體</returns>
????????public?BaseUserInfo?UserLogin(BaseUserInfo?userInfo,?string?userName,?string?password,?out?string?statusCode,?out?string?statusMessage)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????BaseUserInfo?returnUserInfo?=?null;
????????????statusCode?=?string.Empty;
????????????statusMessage?=?string.Empty;
????????????
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????//?先偵測是否在線
????????????????userManager.CheckOnLine();
????????????????//?再進(jìn)行登錄
????????????????returnUserInfo?=?userManager.Login(userName,?password,?userInfo.IPAddress,?userInfo.MACAddress,?out?statusCode);
????????????????if?(returnUserInfo?!=?null)
????????????????{
????????????????????PermissionService?permissionService?=?new?PermissionService();
????????????????????returnUserInfo.IsAdministrator?=?permissionService.IsAdministratorByUser(dbHelper,?userInfo,?returnUserInfo.Id);
????????????????}
????????????????statusMessage?=?userManager.GetStateMessage(statusCode);
????????????????//?登錄時會自動記錄進(jìn)行日志記錄,所以不需要進(jìn)行重復(fù)日志記錄
????????????????//?BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?returnUserInfo;
????????}
????????#endregion
????????#region?public?void?OnExit(BaseUserInfo?userInfo)?用戶退出應(yīng)用程序
????????///?<summary>
????????///?用戶退出應(yīng)用程序
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????public?void?OnExit(BaseUserInfo?userInfo)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????userManager.OnExit(userInfo.Id);
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????}
????????#endregion
????????#region?public?int?ServerCheckOnLine()?服務(wù)器端檢查在線狀態(tài)
????????///?<summary>
????????///?服務(wù)器端檢查在線狀態(tài)
????????///?</summary>
????????///?<returns>離線人數(shù)</returns>
????????public?int?ServerCheckOnLine()
????????{
????????????int?returnValue?=?0;
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper);
????????????????returnValue?=?userManager.CheckOnLine();
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseInterfaceLogic.WriteException(ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????return?returnValue;
????????}
????????#endregion
????????#region?public?int?CheckOnLine(BaseUserInfo?userInfo)?檢查在線狀態(tài)
????????///?<summary>
????????///?檢查在線狀態(tài)
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>離線人數(shù)</returns>
????????public?int?CheckOnLine(BaseUserInfo?userInfo)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????int?returnValue?=?0;
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper);
????????????????//?設(shè)置為在線狀態(tài)
????????????????userManager.OnLine(userInfo.Id);
????????????????returnValue?=?userManager.CheckOnLine();
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseInterfaceLogic.WriteException(ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?returnValue;
????????}
????????#endregion
????????#region?public?DataTable?GetOnLineState(BaseUserInfo?userInfo)?獲取在線用戶列表
????????///?<summary>
????????///?獲取在線用戶列表
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<returns>數(shù)據(jù)表</returns>
????????public?DataTable?GetOnLineState(BaseUserInfo?userInfo)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????DataTable?dataTable?=?new?DataTable();
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????if?(MessageService.LaseCheck?==?DateTime.MinValue)
????????????????{
????????????????????//?設(shè)置為在線狀態(tài)
????????????????????userManager.OnLine(userInfo.Id);
????????????????????//?檢查用戶在線狀態(tài)(服務(wù)器專用)
????????????????????userManager.CheckOnLine();
????????????????????MessageService.LaseCheck?=?DateTime.Now;
????????????????}
????????????????else
????????????????{
????????????????????//?2008.01.23?JiRiGaLa?修正錯誤
????????????????????TimeSpan?timeSpan?=?DateTime.Now?-?MessageService.LaseCheck;
????????????????????if?((timeSpan.Minutes?*?60?+?timeSpan.Seconds)?>=?BaseSystemInfo.OnLineCheck)
????????????????????{
????????????????????????//?設(shè)置為在線狀態(tài)
????????????????????????userManager.OnLine(userInfo.Id);
????????????????????????//?檢查用戶在線狀態(tài)(服務(wù)器專用)
????????????????????????userManager.CheckOnLine();
????????????????????????MessageService.LaseCheck?=?DateTime.Now;
????????????????????}
????????????????}
????????????????//?獲取在線狀態(tài)列表
????????????????dataTable?=?userManager.GetOnLineStateDT();
????????????????//?BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?dataTable;
????????}
????????#endregion
????????#region?public?int?SetPassword(BaseUserInfo?userInfo,?string[]?userIds,?string?password,?out?string?statusCode,?out?string?statusMessage)?設(shè) 置密碼
????????///?<summary>
????????///?設(shè)置密碼
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="userId">被設(shè)置的職員主鍵</param>
????????///?<param?name="password">新密碼</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>影響行數(shù)</returns>
????????public?int?SetPassword(BaseUserInfo?userInfo,?string[]?userIds,?string?password,?out?string?statusCode,?out?string?statusMessage)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????statusCode?=?string.Empty;
????????????statusMessage?=?string.Empty;
????????????int?returnValue?=?0;
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????returnValue?=?userManager.BatchSetPassword(userIds,?password,?out?statusCode);
????????????????//?獲得狀態(tài)消息
????????????????statusMessage?=?userManager.GetStateMessage(statusCode);
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?returnValue;
????????}
????????#endregion
????????
????????#region?public?int?ChangePassword(BaseUserInfo?userInfo,?string?oldPassword,?string?newPassword,?out?string?statusCode,?out?string?statusMessage)?修 改密碼
????????///?<summary>
????????///?修改密碼
????????///?</summary>
????????///?<param?name="userInfo">用戶</param>
????????///?<param?name="oldPassword">原始密碼</param>
????????///?<param?name="newPassword">新密碼</param>
????????///?<param?name="statusCode">返回狀態(tài)碼</param>
????????///?<param?name="statusMessage">返回狀消息</param>
????????///?<returns>影響行數(shù)</returns>
????????public?int?ChangePassword(BaseUserInfo?userInfo,?string?oldPassword,?string?newPassword,?out?string?statusCode,?out?string?statusMessage)
????????{
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????int?milliStart?=?BaseBusinessLogic.StartDebug(userInfo,?MethodBase.GetCurrentMethod());
????????????#endif
????????????statusCode?=?string.Empty;
????????????statusMessage?=?string.Empty;
????????????int?returnValue?=?0;
????????????IDbHelper?dbHelper?=?DbHelperFactory.GetHelper();
????????????try
????????????{
????????????????dbHelper.Open();
????????????????//?事務(wù)開始
????????????????//?dbHelper.BeginTransaction();
????????????????BaseLogManager.Instance.Add(dbHelper,?userInfo,?MethodBase.GetCurrentMethod());
????????????????BaseUserManager?userManager?=?new?BaseUserManager(dbHelper,?userInfo);
????????????????returnValue?=?userManager.ChangePassword(oldPassword,?newPassword,?out?statusCode);
????????????????//?獲得狀態(tài)消息
????????????????statusMessage?=?userManager.GetStateMessage(statusCode);
????????????????//?事務(wù)遞交
????????????????//?dbHelper.CommitTransaction();
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????//?事務(wù)回滾
????????????????//?dbHelper.RollbackTransaction();
????????????????BaseExceptionManager.LogException(dbHelper,?userInfo,?ex);
????????????????throw?ex;
????????????}
????????????finally
????????????{
????????????????dbHelper.Close();
????????????}
????????????//?寫入調(diào)試信息
????????????#if?(DEBUG)
????????????????BaseBusinessLogic.EndDebug(MethodBase.GetCurrentMethod(),?milliStart);
????????????#endif
????????????return?returnValue;
????????}
????????#endregion
????}
}
?
?
WCF 客戶端程序注意事項
1:如何不用一個個引用,用程序方式,實現(xiàn)各服務(wù)的靈活調(diào)用?
2:返回值的長度限制問題解決、如何進(jìn)行設(shè)置?
3:客戶端多個endpoint的定義如何設(shè)置?最少的配置文件寫法?
?
以下是客戶端的配置文件參考
<?xml?version="1.0"?encoding="utf-8"??><configuration>
??<system.serviceModel>
????<client>
??????<endpoint?address="http://localhost:8888/DotNet.Service/BusinessCardService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IBusinessCardService"??name="DotNet.Service.BusinessCardService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/ExceptionService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IExceptionService"?name="DotNet.Service.ExceptionService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/FileService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IFileService"?name="DotNet.Service.FileService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/FolderService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IFolderService"?name="DotNet.Service.FolderService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/ItemDetailsService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IItemDetailsService"?name="DotNet.Service.ItemDetailsService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/ItemsService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IItemsService"?name="DotNet.Service.ItemsService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/LoginService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.ILoginService"?name="DotNet.Service.LoginService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/LogService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.ILogService"?name="DotNet.Service.LogService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/MessageService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IMessageService"?name="DotNet.Service.MessageService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/ModuleService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IModuleService"?name="DotNet.Service.ModuleService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/OrganizeService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IOrganizeService"?name="DotNet.Service.OrganizeService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/ParameterService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IParameterService"?name="DotNet.Service.ParameterService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/PermissionAdminService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IPermissionAdminService"?name="DotNet.Service.PermissionAdminService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/PermissionService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IPermissionService"?name="DotNet.Service.PermissionService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/RoleService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IRoleService"?name="DotNet.Service.RoleService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/SequenceService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.ISequenceService"?name="DotNet.Service.SequenceService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/StaffService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IStaffService"?name="DotNet.Service.StaffService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/UserService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IUserService"?name="DotNet.Service.UserService"></endpoint>
??????<endpoint?address="http://localhost:8888/DotNet.Service/WorkReportService/"?binding="basicHttpBinding"?bindingConfiguration="HTTP"?contract="DotNet.IService.IWorkReportService"?name="DotNet.Service.WorkReportService"></endpoint>
????</client>
????<bindings>
??????<basicHttpBinding>
????????<binding?name="HTTP"?maxBufferPoolSize="2147483647"?maxReceivedMessageSize="2147483647">
????????</binding>
??????</basicHttpBinding>
????</bindings>
??</system.serviceModel>
</configuration>
?
?
以下是客戶端調(diào)用服務(wù)器端代碼的實現(xiàn)參考
//------------------------------------------------------------//?All?Rights?Reserved?,?Copyright?(C)?2009?,?Jirisoft?,?Ltd.?
//------------------------------------------------------------
using?System.ServiceModel;
namespace?DotNet.WCFClient
{
????using?DotNet.IService;
????///?<summary>
????///?ServiceFactory
????///?本地服務(wù)的具體實現(xiàn)接口
????///?
????///?修改紀(jì)錄
????///?
????///????????2009.09.20?版本:1.0?JiRiGaLa?創(chuàng)建。
????///????????
????///?版本:1.0
????///
????///?<author>
????///????????<name>JiRiGaLa</name>
????///????????<date>2009.09.20</date>
????///?</author>?
????///?</summary>
????public?class?ServiceFactory?:?IServiceFactory
????{
????????public?ISequenceService?CreateSequenceService()
????????{
????????????ChannelFactory<ISequenceService>?channelFactory?=?new?ChannelFactory<ISequenceService>("DotNet.Service.SequenceService");
????????????ISequenceService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IUserService?CreateUserService()
????????{
????????????ChannelFactory<IUserService>?channelFactory?=?new?ChannelFactory<IUserService>("DotNet.Service.UserService");
????????????IUserService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?ILoginService?CreateLoginService()
????????{
????????????ChannelFactory<ILoginService>?channelFactory?=?new?ChannelFactory<ILoginService>("DotNet.Service.LoginService");
????????????ILoginService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?ILogService?CreateLogService()
????????{
????????????ChannelFactory<ILogService>?channelFactory?=?new?ChannelFactory<ILogService>("DotNet.Service.LogService");
????????????ILogService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IExceptionService?CreateExceptionService()
????????{
????????????ChannelFactory<IExceptionService>?channelFactory?=?new?ChannelFactory<IExceptionService>("DotNet.Service.ExceptionService");
????????????IExceptionService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IPermissionAdminService?CreatePermissionAdminService()
????????{
????????????ChannelFactory<IPermissionAdminService>?channelFactory?=?new?ChannelFactory<IPermissionAdminService>("DotNet.Service.PermissionAdminService");
????????????IPermissionAdminService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IOrganizeService?CreateOrganizeService()
????????{
????????????ChannelFactory<IOrganizeService>?channelFactory?=?new?ChannelFactory<IOrganizeService>("DotNet.Service.OrganizeService");
????????????IOrganizeService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IItemsService?CreateItemsService()
????????{
????????????ChannelFactory<IItemsService>?channelFactory?=?new?ChannelFactory<IItemsService>("DotNet.Service.ItemsService");
????????????IItemsService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IItemDetailsService?CreateItemDetailsService()
????????{
????????????ChannelFactory<IItemDetailsService>?channelFactory?=?new?ChannelFactory<IItemDetailsService>("DotNet.Service.ItemDetailsService");
????????????IItemDetailsService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IModuleService?CreateModuleService()
????????{
????????????ChannelFactory<IModuleService>?channelFactory?=?new?ChannelFactory<IModuleService>("DotNet.Service.ModuleService");
????????????IModuleService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IStaffService?CreateStaffService()
????????{
????????????ChannelFactory<IStaffService>?channelFactory?=?new?ChannelFactory<IStaffService>("DotNet.Service.StaffService");
????????????IStaffService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IRoleService?CreateRoleService()
????????{
????????????ChannelFactory<IRoleService>?channelFactory?=?new?ChannelFactory<IRoleService>("DotNet.Service.RoleService");
????????????IRoleService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IMessageService?CreateMessageService()
????????{
????????????ChannelFactory<IMessageService>?channelFactory?=?new?ChannelFactory<IMessageService>("DotNet.Service.MessageService");
????????????IMessageService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IFileService?CreateFileService()
????????{
????????????ChannelFactory<IFileService>?channelFactory?=?new?ChannelFactory<IFileService>("DotNet.Service.FileService");
????????????IFileService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IFolderService?CreateFolderService()
????????{
????????????ChannelFactory<IFolderService>?channelFactory?=?new?ChannelFactory<IFolderService>("DotNet.Service.FolderService");
????????????IFolderService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IParameterService?CreateParameterService()
????????{
????????????ChannelFactory<IParameterService>?channelFactory?=?new?ChannelFactory<IParameterService>("DotNet.Service.ParameterService");
????????????IParameterService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IPermissionService?CreatePermissionService()
????????{
????????????ChannelFactory<IPermissionService>?channelFactory?=?new?ChannelFactory<IPermissionService>("DotNet.Service.PermissionService");
????????????IPermissionService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????????public?IBusinessCardService?CreateBusinessCardService()
????????{
????????????ChannelFactory<IBusinessCardService>?channelFactory?=?new?ChannelFactory<IBusinessCardService>("DotNet.Service.BusinessCardService");
????????????IBusinessCardService?proxy?=?channelFactory.CreateChannel();
????????????return?proxy;
????????}
????}
}
?
程序的運行效果如下圖:
?
?
以上的寫法核心解決的問題有:
WCF服務(wù)器端、WCF客戶端配置文件的正確寫法。
多個服務(wù)的定義及調(diào)用方法。
用程序、接口的方式調(diào)用WCF服務(wù),減少命名空間不同,無法正常調(diào)用遠(yuǎn)程WCF服務(wù)的問題,這樣程序用最少的改動量,支持WCF技術(shù)了。
只要入門了,接下就是肯投入多少時間,在于研究什么細(xì)節(jié)問題了,鋪平了入門的道路了,進(jìn)入了軌道了,發(fā)展就快了。
http://www.cnblogs.com/jirigala/archive/2010/06/09/1754588.html總結(jié)
以上是生活随笔為你收集整理的.NET疯狂架构经验分享系列之(七)WCF支持(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几个简单的shell脚本
- 下一篇: 人也女马白勺