2009-02-09 30 views
7

Với lớp MarshalByRef này: Mã phíaXác định các khách hàng trong một invocation .NET Remoting

public class MyRemotedClass : MarshalByRef 
{ 
    public void DoThis() 
    { 
    ... 
    } 
    public void DoThat() 
    { 
    ... 
    } 
} 

Chủ đầu tư:

MyRemotedClass m = GetSomehowMyRemotedClass(); 
m.DoThis(); 
m.DoThat(); 

tôi có thể có một số khách hàng làm điều tương tự tại một thời. Tôi muốn phân biệt các khách hàng. Làm thế nào tôi có thể xác định bên trong các phương thức truy cập từ xa, người mà lời gọi truy cập từ xa được thực thi? Ví dụ: tôi có thể đăng nhập ai đã làm gì. (Trên thực tế, tôi không cần phải theo dõi lại các thông tin khách hàng thực sự, tôi chỉ muốn để có thể viện dẫn nhóm của khách hàng.)

[Edited thêm chi tiết nền]

tôi có số lượng lớn mã để bao gồm, bao gồm cả tài sản. Do đó việc mở rộng danh sách tham số đầu vào không phải là một tùy chọn.

Trả lời

15

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(); 
    } 
} 
+4

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

+2

@ 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

+0

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

Các vấn đề liên quan