2009年3月18日星期三

在ArcGIS Server程序中连接GIS Server的注意事项

        为什么要在ArcGIS Server的程序中来连接GIS Server呢?通常有两个理由:1、连接后,创建ServerContext,之后创建更多的AO对象,从而在程序中调用AO来工作;2、连接后,可以用来管理GIS Server,比如重新启动某个服务。
        先解释两个概念。这里所说的ArcGIS Server程序是指利用了GIS Server上资源的程序,包括了Desktop Application,Engine Application,但最常见的还是Web Application;要调用AO来服务自己的AGS程序,就必须通过局域网直接连接到SOM机器,因为ArcObjects实际上寄存在SOC机器上,而我们是不能与SOC直接打交道的,只能通过SOM来完成这项工作(通过Internet连接的方式只能连接到Web Server)。
        好了,要通过程序来连接到GIS Server,主要有两个对象可以使用:ESRI.ArcGIS.Server.GISServerConnection(实现了IGISServerConnection2接口)和ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection。前者是com对象,后者是原生的.net对象。
        先来看ESRI.ArcGIS.Server.GISServerConnection。使用方法如下:
ESRI.ArcGIS.Server.IGISServerConnection2 pGISSC = new ESRI.ArcGIS.Server.GISServerConnectionClass();
pGISSC.Connect("yourservername");
ESRI.ArcGIS.Server.IServerObjectAdmin pAdm = pGISSC.ServerObjectAdmin;
注意,要成功获得pGISSC.ServerObjectAdmin属性得有一个前提条件,就是运行当前AGS程序(注意看前面对AGS程序的解释)的用户必须是agsadmin组里的成员。那么接下来就可以通过IServerObjectAdmin来对GIS Server进行管理了;如果运行当前AGS程序的用户只是agsuser组里的成员,那么你只能获得ServerObjectManager,从而通过IServerObjectManager来创建AO对象,但是不能对GIS Server进行管理;如果运行当前AGS程序的用户既不是agsuser成员也不是agsadmin成员,那么在connect的时候就会报错了。可以看出ESRI.ArcGIS.Server.GISServerConnection对象不能显式指定连接GIS Server的用户。那么连接GIS Server的用户身份很重要吗?下面通过Web Application来说明一下。
        新建一个website,在其中使用如上的代码,调试,通过;将网站发布,浏览,将会出现“拒绝访问”的错误。这正是因为连接GIS Server的用户身份发生了变化。在VS中调试的时候,调用的是VS自带的ASP.NET程序,而不是IIS中的ASP.NET。如下图:
可以看出,调试的进程是以系统管理员身份运行的,而通常在安装完AGS后会将系统管理员添加到agsadmin组中;网站发布后,web app运行在IIS进程中,而IIS进程通常以ASPNET账户身份运行,正常情况下,这个账户当然既不属于agsadmin也不属于agsuser了。
        同理,如果是Desktop或者Engine的程序,在调试阶段和上面的情况是一致的,如果程序部署到了其他机器上,那么就得考虑一些添加用户的工作了。
        下面再来看ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection。这是ADF中的.net对象,通常推荐使用这个对象来进行连接工作,因为它可以指定使用特定的账户身份来连接GIS Server,就是下面的Identity:
ESRI.ArcGIS.ADF.Identity identity = new ESRI.ArcGIS.ADF.Identity("yourusername", "yourpassword", "yourdomain");
ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconnection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection("yourgisservername", identity);
agsconnection.Connect();
ESRI.ArcGIS.Server.IServerObjectAdmin pAdm = agsconnection.ServerObjectAdmin;
同样的,要成功获得pAdm,Identity中指定的用户必须是agsadmin成员。如果你的网站,在调试时可以运行,而发布后“拒绝访问”,那么首先检查web.config的identity,如果使用了以上代码,请确保使用的user在正确的用户组中。
        再来看看这个Identity与web.config中的identity属性的区别。1、此处的Identity优先级比web.config中的identity属性要高。举例说明,如果在VS中已经做过Add ArcGIS Identity,添加了一个agsuser成员,那么可以在此处用agsadmin成员来连接GIS Server,依然可以获得对SOM机器的管理权限。2、web.config中的identity是在process级别上的impersonation,而此处的Identity是thread级别上的impersonation。如果服务是pooled,low isolation,那么并发请求发生时,会有多个instance运行在同一进程中,而这些instance(thread)就可以通过上面的Identity来以不同用户身份对GIS Server进行连接了。例如:
public partial class _Default : System.Web.UI.Page
{
private UserThread m_thread;

protected void Button1_Click(object sender, EventArgs e)
{
m_thread = new UserThread();
Thread t = new Thread(new ThreadStart(m_thread.Connection1));
t.Start();
Thread t2 = new Thread(new ThreadStart(m_thread.Connection2));
t2.Start();
}
}

public class UserThread
{
public void Connection1()
{
ESRI.ArcGIS.ADF.Identity id = new ESRI.ArcGIS.ADF.Identity("user1", "pass1", "domain1");
ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconn;
agsconn = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection("server1", id);
agsconn.Connect();
}

public void Connection2()
{
ESRI.ArcGIS.ADF.Identity id = new ESRI.ArcGIS.ADF.Identity("user2", "pass2", "domain2");
ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconn;
agsconn = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection("server2", id);
agsconn.Connect();
}
}

没有评论:

发表评论