Пример удаленного взаимодействия. Размещение в службах IIS

Этот раздел относится к технологии прежних версий, которая сохраняется для обеспечения обратной совместимости с существующими приложениями и не рекомендуется для разработки новых приложений. Сейчас распределенные приложения следует создавать с помощью  Windows Communication Foundation (WCF).

В следующем образце реализуется базовая веб-служба с несколькими дополнениями. Объект BinaryFormatter используется потому, что нагрузка невелика и система тратит меньше времени на сериализацию и десериализацию потока. Кроме того, если службы IIS используют встроенную проверку подлинности Windows (также называемую проверкой подлинности NTLM), сервер проверяет подлинность клиента и возвращает клиенту удостоверение, которое удалось проверить службам IIS. Наконец, можно защитить веб-службу, изменив URL-адрес в файле конфигурации клиента, чтобы в качестве протокола использовался "https", а также настроить службы IIS таким образом, чтобы они требовали шифрования с помощью протокола SSL для соответствующего виртуального каталога (в данном примере этот процесс не показан).

c2swb8ah.Caution(ru-ru,VS.100).gifВнимание!
По умолчанию при удаленном взаимодействии .NET Framework проверка подлинности и шифрование не выполняются. Поэтому рекомендуется принять все необходимые меры для проверки удостоверений клиентов и серверов до удаленного взаимодействия с ними. Поскольку для запуска приложений, использующих удаленное взаимодействие .NET Framework, требуются разрешения FullTrust, если неавторизованный клиент получит доступ к серверу, клиент сможет запускать код так, как если бы он был полностью доверенным. Всегда выполняйте проверку подлинности конечных точек и шифрование потоков взаимодействия, либо разместив типы, поддерживающие удаленное взаимодействие, в службах IIS, либо создав пользовательскую пару приемников каналов для выполнения этих задач.

Компиляция и выполнение примера

  1. Сохраните все файлы в каталоге с именем RemoteIIS.

  2. Скомпилируйте весь образец, воспользовавшись следующими командами командной строки.

    vbc /t:library ServiceClass.vb
    vbc /r:System.Runtime.Remoting.dll /r:ServiceClass.dll Client.vb
    
    csc /t:library ServiceClass.cs
    csc /r:System.Runtime.Remoting.dll /r:ServiceClass.dll Client.cs
    
  3. Создайте подкаталог \bin и скопируйте в него файл ServiceClass.dll.

  4. Создайте приложение в IIS. Создайте псевдоним приложения HttpBinary и сделайте каталог RemoteIIS исходным.

  5. Установите в качестве метода проверки подлинности этого виртуального каталога встроенную проверку подлинности Windows (прежнее название — проверка подлинности NTLM). Если выбран анонимный доступ, свойство HttpContext.Current.User.Identity.Name будет иметь значение NULL, а метод GetServerString будет возвращать в качестве псевдонима пользователя значение "***unavailable***". Чтобы избежать этого, отключите анонимный доступ.

  6. Убедитесь, что службы IIS запущены; в командной строке в каталоге RemoteIIS введите client.

Это приложение выполняется на одном компьютере или в сети. Если требуется запускать это приложение в сети, необходимо в конфигурации клиента заменить "localhost" на имя удаленного компьютера.

ServiceClass

Imports System
Imports System.Runtime.Remoting
Imports System.Web

Public Interface IService
    Function GetServerTime() As DateTime
    Function GetServerString() As String
End Interface

Public Class ServiceClass
    Inherits MarshalByRefObject
    Implements IService

    Private InstanceHash As Integer

    Public Sub New()
        InstanceHash = Me.GetHashCode()
    End Sub

    Public Function GetServerTime() As Date Implements IService.GetServerTime
        Return DateTime.Now
    End Function

    Public Function GetServerString() As String Implements IService.GetServerString
        ' Use the HttpContext to acquire what IIS thinks the client's identity is.
        Dim temp As String = HttpContext.Current.User.Identity.Name

        If (temp Is Nothing Or temp.Equals(String.Empty)) Then
            temp = "**unavailable**"
        End If

        Return "Hi there. You are being served by instance number: " _
            & InstanceHash.ToString() _
            & ". Your alias is: " _
            & temp
    End Function
End Class
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Web;

public interface IService
{
   DateTime GetServerTime();
   string GetServerString();
}

// IService exists to demonstrate the possibility of publishing only the interface.
public class ServiceClass : MarshalByRefObject, IService
{
   private int InstanceHash;

   public ServiceClass()
   {
      InstanceHash = this.GetHashCode();
   }

   public DateTime GetServerTime()
   {
      return DateTime.Now;
   }

   public string GetServerString()
   {
      // Use the HttpContext to acquire what IIS thinks the client's identity is.
      string temp = HttpContext.Current.User.Identity.Name;
      if (temp == null || temp.Equals(string.Empty))
         temp = "**unavailable**";
      return "Hi there. You are being served by instance number: " 
         + InstanceHash.ToString() 
         + ". Your alias is: " 
         + temp;
   }
}

Web.config

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown 
               mode="SingleCall" objectUri="SAService.rem"
               type="ServiceClass, ServiceClass"/>
         </service>
         <channels>
            <channel ref="http"/>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>

Клиент

Imports System
Imports System.Collections
Imports System.Net
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Security.Principal

Public Class Client

    Public Shared Sub Main()
        ' Tells the system about the remote object and customizes the HttpChannel
        ' to use the binary formatter (which understands that base64 encoding is needed).
        RemotingConfiguration.Configure("Client.exe.config", False)

        ' New proxy for the ServiceClass.
        ' If you publish only the IService interface, you must use Activator.GetObject.
        Dim service As ServiceClass = New ServiceClass()

        ' Programmatically customizes the properties given to the channel. This sample uses the
        '  application configuration file.
        Dim Props As IDictionary = ChannelServices.GetChannelSinkProperties(service)
        Props.Item("credentials") = CredentialCache.DefaultCredentials

        ' Reports the client identity name.
        Console.WriteLine("ConsoleIdentity: " & WindowsIdentity.GetCurrent().Name)

        ' Writes what the server returned.
        Console.WriteLine("The server says : " & service.GetServerString())
        Console.WriteLine("Server time is: " & service.GetServerTime())
    End Sub
End Class
using System;
using System.Collections;
using System.Net;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;

class Client
{
    static void Main(string[] args)
    {
        // Tells the system about the remote object and customizes the HttpChannel
        // to use the binary formatter (which understands that base64 encoding is needed).
        RemotingConfiguration.Configure("Client.exe.config", false);

        // New proxy for the ServiceClass.
        // If you publish only the IService interface, you must use Activator.GetObject.
        ServiceClass service = new ServiceClass();

        // Programmatically customizes the properties given to the channel. This sample uses the
        // application configuration file.
        IDictionary Props = ChannelServices.GetChannelSinkProperties(service);
        Props["credentials"] = CredentialCache.DefaultCredentials;

        // Reports the client identity name.
        Console.WriteLine("ConsoleIdentity: " + WindowsIdentity.GetCurrent().Name);

        // Writes what the server returned.
        Console.WriteLine("The server says : " + service.GetServerString());
        Console.WriteLine("Server time is: " + service.GetServerTime());
    }
}

Client.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel ref="http" useDefaultCredentials="true" port="0">
          <clientProviders>
            <formatter 
               ref="binary"
                  />
          </clientProviders>
        </channel>
      </channels>
      <client>
        <wellknown 
           url="https://localhost:80/HttpBinary/SAService.rem"
           type="ServiceClass, ServiceClass"
            />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

См. также

Основные понятия

Конфигурация удаленных приложений
Размещение удаленных объектов в службах IIS

Другие ресурсы

Примеры удаленного взаимодействия