Một trong những điều bạn có thể làm là xác định khách hàng theo địa chỉ IP bằng cách triển khai IServerChannelSinkProvider
.
Thêm lớp này đến dự án máy chủ truy cập từ xa của bạn:
ClientIPServerSinkProvider.cs
using System;
using System.Collections;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Net;
namespace MyRemotingEnvironment
{
public class ClientIPServerSinkProvider :
IServerChannelSinkProvider
{
private IServerChannelSinkProvider _nextProvider = null;
public ClientIPServerSinkProvider()
{
}
public ClientIPServerSinkProvider(
IDictionary properties,
ICollection providerData)
{
}
public IServerChannelSinkProvider Next
{
get { return _nextProvider; }
set { _nextProvider = value; }
}
public IServerChannelSink CreateSink(IChannelReceiver channel)
{
IServerChannelSink nextSink = null;
if (_nextProvider != null)
{
nextSink = _nextProvider.CreateSink(channel);
}
return new ClientIPServerSink(nextSink);
}
public void GetChannelData(IChannelDataStore channelData)
{
}
}
public class ClientIPServerSink :
BaseChannelObjectWithProperties,
IServerChannelSink,
IChannelSinkBase
{
private IServerChannelSink _nextSink;
public ClientIPServerSink(IServerChannelSink next)
{
_nextSink = next;
}
public IServerChannelSink NextChannelSink
{
get { return _nextSink; }
set { _nextSink = value; }
}
public void AsyncProcessResponse(
IServerResponseChannelSinkStack sinkStack,
Object state,
IMessage message,
ITransportHeaders headers,
Stream stream)
{
IPAddress ip = headers[CommonTransportKeys.IPAddress] as IPAddress;
CallContext.SetData("ClientIPAddress", ip);
sinkStack.AsyncProcessResponse(message, headers, stream);
}
public Stream GetResponseStream(
IServerResponseChannelSinkStack sinkStack,
Object state,
IMessage message,
ITransportHeaders headers)
{
return null;
}
public ServerProcessing ProcessMessage(
IServerChannelSinkStack sinkStack,
IMessage requestMsg,
ITransportHeaders requestHeaders,
Stream requestStream,
out IMessage responseMsg,
out ITransportHeaders responseHeaders,
out Stream responseStream)
{
if (_nextSink != null)
{
IPAddress ip =
requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;
CallContext.SetData("ClientIPAddress", ip);
ServerProcessing spres = _nextSink.ProcessMessage(
sinkStack,
requestMsg,
requestHeaders,
requestStream,
out responseMsg,
out responseHeaders,
out responseStream);
return spres;
}
else
{
responseMsg = null;
responseHeaders = null;
responseStream = null;
return new ServerProcessing();
}
}
}
}
Sau đó, khi bạn bắt đầu máy chủ truy cập từ xa của bạn làm điều gì đó như sau:
BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider();
ClientIPServerSinkProvider csp = new ClientIPServerSinkProvider();
csp.Next = bp;
Hashtable ht = new Hashtable();
ht.Add("port", "1234"); // Your remoting port number
TcpChannel channel = new TcpChannel(ht, null, csp);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(MyRemotedClass),
"MyRemotedClass.rem",
WellKnownObjectMode.SingleCall);
Trong phương pháp của bạn gọi cho bạn có thể truy cập địa chỉ IP của khách hàng bằng cách thực hiện:
public class MyRemotedClass : MarshalByref
{
public void DoThis()
{
string clientIP = CallContext.GetData("ClientIPAddress").ToString();
}
}
Có thực sự phức tạp này chỉ để có được một địa chỉ IP của khách hàng? – IAbstract
@ dboarman - đó là cách duy nhất. Nhưng nếu bạn đã quen với việc viết các lớp học chìm trong kênh của riêng mình thì nó sẽ trở thành một phần bình thường trong việc từ chối cuộc sống. – Kev
Vâng, thật không may cho tôi đây thực sự là bước đột phá đầu tiên của tôi vào Remoting ... mà tôi đang dành cho bây giờ. Tôi không quan tâm đến việc sử dụng Remoting khi tôi có thể triển khai protobuf-net của Marc Gravell :) Tôi sẽ đi theo một hướng hơi khác cho bây giờ ... cảm ơn sự giúp đỡ của bạn, tho. – IAbstract