poorServer 代码
using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
[assembly: ApplicationName("POOLINGTEST")]
[assembly: AssemblyKeyFile("poolserver.snk")]
namespace PoolServer
{
[ObjectPooling(Enabled=true,MinPoolSize=0, MaxPoolSize=1,CreationTimeout=2000)]
[JustInTimeActivation(true)]
[ConstructionEnabled(Default="Workstation id=DEVELOPER;data source=DEVELOPER;initial catalog=pubs;user id=sa;password=;")] //Text File to be created during construction
public class PooledFile : ServicedComponent
{
private string strConnection;
protected override void Construct(string constructString)
{
strConnection = constructString;
}
public string ConnectionString
{
get
{
return strConnection;
}
}
}
}
-------------------------------------------------------------------------------------------------------------------------------
Q1:抛出安全异常和远程异常。几乎是遵照样例完成,过程很顺利,没有产生任何语法错误,但产生时运行异常,如问题1。
A1:Clinet需要向COM+存储过程远程调用发出参数SqlParameter[],这是非基本类型,且Microsoft也没打算让它可序列化,当这些复杂对象通过网络传输时,必须在Client进行序列化,将SqlParameter[]序列化为二进制流,然后在远程接收到二进制流后,再进行反序列化,即将二进制流转换为SqlParameter[]。由于SqlParameter不支持序列化,只能“曲线救国”,设计一个类ESqlParameter,设置[Serializable],并且在该类中实现可以和SqlParameter进行相互任意转换的方法,至此该运行时异常解除。
-------------------------------------------------------------------------------------------------------------------------------
序列化代码:
IFormatter formatter = new BinaryFormatter();
FileStream file=new FileStream("MyFile.dat", FileMode.Create, FileAccess.ReadWrite, FileShare.None);
Stream stream=(Stream)(file);
formatter.Serialize(stream, eparam);
stream.Seek(0, SeekOrigin.Begin);
SqlDataReader dr = loader.executeQueryProcedure("prcGetEmpName", stream);
file.Close();
stream.Close();
-------------------------------------------------------------------------------------------------------------------------------
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
ESqlParameter[] eparam = (ESqlParameter []) formatter.Deserialize(stream);
stream.Close();
SqlParameter param = new SqlParameter();
Q2:解决了Q1,但依然产生运行时异常,提示信道(管道)未注册、多次注册、安全异常等之类的异常。 A2:对于远程传递参数,尤其是非基本类型参数,接收、传递和处理时可能存在权限不够的问题,重新修改Remoting Server和Clinet注册信道的方法,以设置较为合适的权限。
-------------------------------------------------------------------------------------------------------------------------------
Remoting Server代码:
RemotingConfiguration.Applicati;
RemotingConfiguration.RegisterActivatedServiceType(typeof(RemoteTest.SQLConnection));
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"]=9000;
TcpChannel channel = new TcpChannel(props,clientProvider,serverProvider);
ChannelServices.RegisterChannel(channel);
-------------------------------------------------------------------------------------------------------------------------------
Client代码:
RemotingConfiguration.RegisterActivatedClientType(typeof(RemoteTest.SQLConnection),"tcp://localhost:9000/TestLoader");
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props=new Hashtable();
props["port"]=0;
TcpChannel channel = new TcpChannel(props,clientProvider,serverProvider);
ChannelServices.RegisterChannel(channel);
SQLConnection loader = new SQLConnection();
至此,异常不再产生,经受了多数的测试。后来,受启发,将Remoting Server设计成托盘程序,类似于Microsoft SQL Server的服务管理器、MySQL和Tomcat等服务器程序,不占任务栏地盘,只需选择启动和停止,出现不同的图标和不同远程服务器的状态。