Одна из вещей, которую вы можете сделать, это идентифицировать клиента по IP-адресу путем реализации IServerChannelSinkProvider
.
Добавить этот класс в проект хоста удаленного взаимодействия:
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();
}
}
}
}
Тогда при запуске удаленного взаимодействия хоста сделать что-то вроде следующего:
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);
В вашем методе звонит может получить доступ к IP-адресу клиента:
public class MyRemotedClass : MarshalByref
{
public void DoThis()
{
string clientIP = CallContext.GetData("ClientIPAddress").ToString();
}
}
Действительно ли это сложно только для получения IP-адреса клиента? – IAbstract
@ dboarman - это единственный способ. Но если вы привыкли писать свои собственные каналы раковины, то это становится нормальной частью жизни. – Kev
Да, к сожалению, для меня это действительно мой первый набег на Remoting ... который я откладываю сейчас. Я не хочу использовать Remoting, когда я могу реализовать protobuf-net Марка Гравелла :) Я сейчас немного в другом направлении ... спасибо за помощь, тo. – IAbstract