Пример удаленного взаимодействия. Размещение в службах IIS
Этот раздел относится к технологии прежних версий, которая сохраняется для обеспечения обратной совместимости с существующими приложениями и не рекомендуется для разработки новых приложений. Сейчас распределенные приложения следует создавать с помощью Windows Communication Foundation (WCF).
В следующем образце реализуется базовая веб-служба с несколькими дополнениями. Объект BinaryFormatter используется потому, что нагрузка невелика и система тратит меньше времени на сериализацию и десериализацию потока. Кроме того, если службы IIS используют встроенную проверку подлинности Windows (также называемую проверкой подлинности NTLM), сервер проверяет подлинность клиента и возвращает клиенту удостоверение, которое удалось проверить службам IIS. Наконец, можно защитить веб-службу, изменив URL-адрес в файле конфигурации клиента, чтобы в качестве протокола использовался "https", а также настроить службы IIS таким образом, чтобы они требовали шифрования с помощью протокола SSL для соответствующего виртуального каталога (в данном примере этот процесс не показан).
![]() |
---|
По умолчанию при удаленном взаимодействии .NET Framework проверка подлинности и шифрование не выполняются. Поэтому рекомендуется принять все необходимые меры для проверки удостоверений клиентов и серверов до удаленного взаимодействия с ними. Поскольку для запуска приложений, использующих удаленное взаимодействие .NET Framework, требуются разрешения FullTrust, если неавторизованный клиент получит доступ к серверу, клиент сможет запускать код так, как если бы он был полностью доверенным. Всегда выполняйте проверку подлинности конечных точек и шифрование потоков взаимодействия, либо разместив типы, поддерживающие удаленное взаимодействие, в службах IIS, либо создав пользовательскую пару приемников каналов для выполнения этих задач. |
Компиляция и выполнение примера
Сохраните все файлы в каталоге с именем RemoteIIS.
Скомпилируйте весь образец, воспользовавшись следующими командами командной строки.
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
Создайте подкаталог \bin и скопируйте в него файл
ServiceClass.dll
.Создайте приложение в IIS. Создайте псевдоним приложения HttpBinary и сделайте каталог RemoteIIS исходным.
Установите в качестве метода проверки подлинности этого виртуального каталога встроенную проверку подлинности Windows (прежнее название — проверка подлинности NTLM). Если выбран анонимный доступ, свойство
HttpContext.Current.User.Identity.Name
будет иметь значение NULL, а методGetServerString
будет возвращать в качестве псевдонима пользователя значение"***unavailable***"
. Чтобы избежать этого, отключите анонимный доступ.Убедитесь, что службы 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