那位高手给一个Remoting的例子看看!小弟没装MSDN!(在线等待!急急急!!)

apollonew 2004-03-22 09:17:51
Server.cs (服务器)
Client.cs (客户端)
RemoteObj.cs (远程对象)
IRemote.cs (远程对象接口)

采用 Client 调用 IRemote 来使用 Server 的 RemoteObj !
我想在 Server 里实现 访问 数据库!返回一个 DataView
所有的数据访问方法都不要在 RemoteObj 里实现!
RemoteObj 只是把访问的结果 DataView 返回给 Client 就行了!
请高手高手高高手指点一二!

分不够再加!!:)
...全文
107 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
apollonew 2004-03-23
  • 打赏
  • 举报
回复
up 一下啊!!救我啊
apollonew 2004-03-23
  • 打赏
  • 举报
回复
理论我知道啊!但用代码怎么做呢?!??!
有没有人给个例子我看看啊!!谢谢啦!很急的啊
apollonew 2004-03-23
  • 打赏
  • 举报
回复
up
apollonew 2004-03-22
  • 打赏
  • 举报
回复
有没有高手指点一下啊!
我主要是想知道怎么在 Client 使用接口的方法啊!

还有就是 DataView 怎么返回给 Client! 当然前提条件是 SqlConnection 不要做在
RemoteObj 里面!

拜托啦!!!搞定后当场结算~~
不够再开新贴给分
apollonew 2004-03-22
  • 打赏
  • 举报
回复
~上面的例子太复杂了~能不能搞个简单的!
只是能说明一下我要的那个例子就行了!
tl0 2004-03-22
  • 打赏
  • 举报
回复
Client.cs
using System;
using System.Runtime.Remoting;

public class Client{

public static void Main(string[] Args){

RemotingConfiguration.Configure("Client.exe.config");
ServiceClass service = new ServiceClass();
Console.WriteLine(service.GetServerTime());
}
}
Server.cs
using System;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

public class ServerProcess{

public static void Main(string[] Args){

RemotingConfiguration.Configure("server.exe.config");
Console.WriteLine("Press enter to stop this process.");
Console.ReadLine();

}
}
ServiceClass.cs
using System;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;

public class ServiceClass : MarshalByRefObject{

private DateTime starttime;

public ServiceClass(){
Console.WriteLine("A ServiceClass has been created.");
starttime = DateTime.Now;
}

~ServiceClass(){
Console.WriteLine("This object is being collected after " + (new TimeSpan(DateTime.Now.Ticks - starttime.Ticks)).ToString() + " seconds.");

}

public DateTime GetServerTime(){
Console.WriteLine("Time requested by a client.");
return DateTime.Now;
}

}
Client.exe.config
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type="ServiceClass, ServiceClass"
url="http://localhost:8080/RemoteObject"
/>
</client>
<channels>
<channel ref="http">
<clientProviders>
<formatter ref="soap"/>
<provider ref="propsetter" username="bob" writeToConsole="true">
<endpoint allowAutoRedirect="true"/>
<endpoint preauthenticate="true"/>
<endpoint url="example.com:9000" password="xyz" />
<endpoint url="example.com:9001" password="123" />
<endpoint timeout="10000"/>
<endpoint url="example.com:*" username="bob2" password="qwerty" domain="hello" />
</provider>
</clientProviders>
</channel>
</channels>
</application>
<channelSinkProviders>
<clientProviders>
<provider
id="propsetter"
type="ChannelSinkPropertySetterProvider, PropsSink"
/>
</clientProviders>
</channelSinkProviders>
<debug loadTypes="true" />
</system.runtime.remoting>
</configuration>
Server.exe.config
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall"
type="ServiceClass, ServiceClass"
objectUri="RemoteObject"
/>
</service>
<channels>
<channel port="8080" ref="http" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
tl0 2004-03-22
  • 打赏
  • 举报
回复
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.MetadataServices;

// This class implements a client-side channel sink provider that
// walks the channel sink chain, looking for channel sink
// properties that match those specified in the configuration file. If it
// finds them, the provider sets them to the values specified in the
// configuration file. This is a simple helper provider that returns no
// channel itself. Instead, it merely returns the next channel sink it can // find, or null.
public class ChannelSinkPropertySetterProvider : IClientChannelSinkProvider{

private IClientChannelSinkProvider _next = null;
private IDictionary _channelSinkProperties = null;
private ICollection _providerData = null;

// Set the writeToConsole attribute on this provider element in the
// configuration file to "true"; otherwise, information is not written to the console.
private bool _consoleDump = false;

// Default constructor.
public ChannelSinkPropertySetterProvider(){
Console.WriteLine("Default constructor called.");

} // ChannelSinkPropertySetterProvider.

// Constructor with properties. If writeToConsole attribute is "true",
// this constructor will dump all custom configuration properties set
// in the configuration file.

public ChannelSinkPropertySetterProvider(IDictionary properties, ICollection providerData){

_channelSinkProperties = properties;

// Sets the private console dump property for this provider.
if (properties["writeToConsole"] != null)
_consoleDump = Boolean.Parse(properties["writeToConsole"].ToString());

_providerData = providerData;

if (_consoleDump){
Console.WriteLine("ChannelSinkPropertySetterProvider custom constructor called.");

foreach(SinkProviderData sinkData in providerData){

Console.WriteLine("SinkProvider element: " + sinkData.Name);
foreach(DictionaryEntry prop in sinkData.Properties){
Console.WriteLine("Prop name: " + prop.Key.ToString() + " value: " + prop.Value.ToString());
}

foreach(object child in sinkData.Children){
Console.WriteLine("Child: " + child.GetType().Name);
}
}

foreach (DictionaryEntry entry in properties){
Console.WriteLine("channel sink properties: " + entry.Key.ToString() + ", " + entry.Value.ToString());
}

Console.WriteLine();
}

} // ChannelSinkPropertySetterProvider.


// Called by the channel. Normally, this method takes any other sinks
// created by other providers in the chain, links them together, and
// then returns its own sink to the channel. In this case, this
// provider merely sets matching properties on each channel sink in the
// chain, and then returns the **next** channel sink to the channel or
// returns null, indicating to the channel that it is the end of the
// custom channel sink chain.
public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData){

if (_consoleDump){
Console.WriteLine("CreateSink is called.");
Console.WriteLine("By " + channel.GetType().Name);
}

IClientChannelSink nextSink = null;

if (_next != null){

nextSink = _next.CreateSink(channel, url, remoteChannelData);

if (nextSink == null){
if (_consoleDump)
Console.WriteLine("Next sink is null!");
return null;
}

WalkSinkChain(nextSink);

}

return nextSink;

}

// This call walks the sink chain, setting properties as it goes.
// The channelSinkProperties are the SinkProviderData dictionaries
// that contain the name of the subnode in the configuration file, and
// a dictionary entry of attribute/value entries on that element.

private void WalkSinkChain(IClientChannelSink thisSink){

if (thisSink == null)
return;

if (_consoleDump)
Console.WriteLine("\r\n\tWalking the sink chain to find sink properties... \r\n");

while(thisSink != null){
if (_consoleDump){
Console.WriteLine(new String('_',80));
Console.WriteLine("Next sink is : " + thisSink.GetType().Name);
DumpSinkProperties(thisSink);
}
SetSinkProperties(thisSink);
thisSink = thisSink.NextChannelSink;
}

return;
}

private void DumpSinkProperties(IClientChannelSink sink){

if (sink.Properties == null){
Console.WriteLine("There are no properties available on the " + sink.GetType().Name + " channelsink.");
return;
}

foreach(DictionaryEntry entry in sink.Properties){
Console.Write("ChannelSink property: " + entry.Key.ToString() + " value: ");
if (entry.Value == null)
Console.WriteLine("No value.");
else
Console.WriteLine(entry.Value.ToString());
}

}

// This method sets properties on the sink.
// The algorithm is that in the absence of instance attribute/value
// entries, the provider element template attribute/value entries will
// be set. This is a simple implementation that does not care about the
// element name underneath the provider element.

private void SetSinkProperties(IClientChannelSink sink){

if (sink.Properties == null){
Console.WriteLine("There are no properties available on the " + sink.GetType().Name + " channelsink.");
return;
}

foreach(DictionaryEntry entry in sink.Properties){
if (_channelSinkProperties.Contains(entry.Key)){

if (_consoleDump)
Console.WriteLine("Setting sink property template on " + sink.GetType().Name + "." + entry.Key.ToString());
sink.Properties[entry.Key] = _channelSinkProperties[entry.Key];
}
}

foreach(SinkProviderData provider in _providerData){
foreach(DictionaryEntry configEntry in provider.Properties){
if (sink.Properties.Contains(configEntry.Key))
if (_consoleDump)
Console.WriteLine("Setting Instance override on " + sink.GetType().Name + "." + configEntry.Key);
sink.Properties[configEntry.Key] = configEntry.Value;
}
}

if (_consoleDump)
DumpSinkProperties(sink);
}

public IClientChannelSinkProvider Next{
get {
return _next;
}

set {
_next = value;
}
}

// This can be called in the constructor in case this provider is
// intended to build its own channel sink provider chain. Without
// providing such a chain, this provider must be specified in a
// configuration file with other providers.
private IClientChannelSinkProvider CreateDefaultClientProviderChain(){

IClientChannelSinkProvider chain = new SoapClientFormatterSinkProvider();
IClientChannelSinkProvider sink = chain;

sink.Next = new BinaryClientFormatterSinkProvider();
sink = sink.Next;

return chain;
} // CreateDefaultClientProviderChain.
} // Class ChannelSinkPropertySetterProvider.
tl0 2004-03-22
  • 打赏
  • 举报
回复
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.MetadataServices;

// This class implements a client-side channel sink provider that
// walks the channel sink chain, looking for channel sink
// properties that match those specified in the configuration file. If it
// finds them, the provider sets them to the values specified in the
// configuration file. This is a simple helper provider that returns no
// channel itself. Instead, it merely returns the next channel sink it can // find, or null.
public class ChannelSinkPropertySetterProvider : IClientChannelSinkProvider{

private IClientChannelSinkProvider _next = null;
private IDictionary _channelSinkProperties = null;
private ICollection _providerData = null;

// Set the writeToConsole attribute on this provider element in the
// configuration file to "true"; otherwise, information is not written to the console.
private bool _consoleDump = false;

// Default constructor.
public ChannelSinkPropertySetterProvider(){
Console.WriteLine("Default constructor called.");

} // ChannelSinkPropertySetterProvider.

// Constructor with properties. If writeToConsole attribute is "true",
// this constructor will dump all custom configuration properties set
// in the configuration file.

public ChannelSinkPropertySetterProvider(IDictionary properties, ICollection providerData){

_channelSinkProperties = properties;

// Sets the private console dump property for this provider.
if (properties["writeToConsole"] != null)
_consoleDump = Boolean.Parse(properties["writeToConsole"].ToString());

_providerData = providerData;

if (_consoleDump){
Console.WriteLine("ChannelSinkPropertySetterProvider custom constructor called.");

foreach(SinkProviderData sinkData in providerData){

Console.WriteLine("SinkProvider element: " + sinkData.Name);
foreach(DictionaryEntry prop in sinkData.Properties){
Console.WriteLine("Prop name: " + prop.Key.ToString() + " value: " + prop.Value.ToString());
}

foreach(object child in sinkData.Children){
Console.WriteLine("Child: " + child.GetType().Name);
}
}

foreach (DictionaryEntry entry in properties){
Console.WriteLine("channel sink properties: " + entry.Key.ToString() + ", " + entry.Value.ToString());
}

Console.WriteLine();
}

} // ChannelSinkPropertySetterProvider.


// Called by the channel. Normally, this method takes any other sinks
// created by other providers in the chain, links them together, and
// then returns its own sink to the channel. In this case, this
// provider merely sets matching properties on each channel sink in the
// chain, and then returns the **next** channel sink to the channel or
// returns null, indicating to the channel that it is the end of the
// custom channel sink chain.
public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData){

if (_consoleDump){
Console.WriteLine("CreateSink is called.");
Console.WriteLine("By " + channel.GetType().Name);
}

IClientChannelSink nextSink = null;

if (_next != null){

nextSink = _next.CreateSink(channel, url, remoteChannelData);

if (nextSink == null){
if (_consoleDump)
Console.WriteLine("Next sink is null!");
return null;
}

WalkSinkChain(nextSink);

}

return nextSink;

}

// This call walks the sink chain, setting properties as it goes.
// The channelSinkProperties are the SinkProviderData dictionaries
// that contain the name of the subnode in the configuration file, and
// a dictionary entry of attribute/value entries on that element.

private void WalkSinkChain(IClientChannelSink thisSink){

if (thisSink == null)
return;

if (_consoleDump)
Console.WriteLine("\r\n\tWalking the sink chain to find sink properties... \r\n");

while(thisSink != null){
if (_consoleDump){
Console.WriteLine(new String('_',80));
Console.WriteLine("Next sink is : " + thisSink.GetType().Name);
DumpSinkProperties(thisSink);
}
SetSinkProperties(thisSink);
thisSink = thisSink.NextChannelSink;
}

return;
}

private void DumpSinkProperties(IClientChannelSink sink){

if (sink.Properties == null){
Console.WriteLine("There are no properties available on the " + sink.GetType().Name + " channelsink.");
return;
}

foreach(DictionaryEntry entry in sink.Properties){
Console.Write("ChannelSink property: " + entry.Key.ToString() + " value: ");
if (entry.Value == null)
Console.WriteLine("No value.");
else
Console.WriteLine(entry.Value.ToString());
}

}

// This method sets properties on the sink.
// The algorithm is that in the absence of instance attribute/value
// entries, the provider element template attribute/value entries will
// be set. This is a simple implementation that does not care about the
// element name underneath the provider element.

private void SetSinkProperties(IClientChannelSink sink){

if (sink.Properties == null){
Console.WriteLine("There are no properties available on the " + sink.GetType().Name + " channelsink.");
return;
}

foreach(DictionaryEntry entry in sink.Properties){
if (_channelSinkProperties.Contains(entry.Key)){

if (_consoleDump)
Console.WriteLine("Setting sink property template on " + sink.GetType().Name + "." + entry.Key.ToString());
sink.Properties[entry.Key] = _channelSinkProperties[entry.Key];
}
}

foreach(SinkProviderData provider in _providerData){
foreach(DictionaryEntry configEntry in provider.Properties){
if (sink.Properties.Contains(configEntry.Key))
if (_consoleDump)
Console.WriteLine("Setting Instance override on " + sink.GetType().Name + "." + configEntry.Key);
sink.Properties[configEntry.Key] = configEntry.Value;
}
}

if (_consoleDump)
DumpSinkProperties(sink);
}

public IClientChannelSinkProvider Next{
get {
return _next;
}

set {
_next = value;
}
}

// This can be called in the constructor in case this provider is
// intended to build its own channel sink provider chain. Without
// providing such a chain, this provider must be specified in a
// configuration file with other providers.
private IClientChannelSinkProvider CreateDefaultClientProviderChain(){

IClientChannelSinkProvider chain = new SoapClientFormatterSinkProvider();
IClientChannelSinkProvider sink = chain;

sink.Next = new BinaryClientFormatterSinkProvider();
sink = sink.Next;

return chain;
} // CreateDefaultClientProviderChain.
} // Class ChannelSinkPropertySetterProvider.
ermachao 2004-03-22
  • 打赏
  • 举报
回复
如果要保证安全的话,应把服务器端与接口分开,客户端用接口时使用Activator.GetObject取到Remoting对象,再使用对象中的方法。
apollonew 2004-03-22
  • 打赏
  • 举报
回复
up 一下
superryu 2004-03-22
  • 打赏
  • 举报
回复
看着头就晕了

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧