Интернет-журнал "Домашняя лаборатория", 2007 №6 - Усманов
Книгу Интернет-журнал "Домашняя лаборатория", 2007 №6 - Усманов читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
Реально контекст вызова передается через ранее упомянутые границы в форме сообщения типа IMessage. В связи с этим и требуется сериализуемость всех передаваемых объектов (т. е. возможность их передачи по значению).
Ниже представлен пример, демонстрирующий применение контекста вызова, пересекающего границу между процессами. За основу взят многократно рассмотренный пример, связанный с перечислением 5 условных единиц со стороны клиента на счет, поддерживаемый сервером.
Рассмотрим прежде всего код сервера.
Сервер
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Threading;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System.Reflection;
namespace MyServer {
[Serializable]
public class MyCallContextUserName:
ILogicalThreadAffinative {
private String _userName;
public MyCallContextUserName() {
_userName = Environment.UserName;
}
public String UserName {
get { return _userName; }
}
}
[Serializable]
public class MyCallContextServerName:
ILogicalThreadAffinative {
private Assembly _assembly;
private String _serverName;
public MyCallContextServerName() {
_assembly = Assembly.GetExecutingAssembly();
_serverName = _assembly.FullName;
}
public String ServerName {
get { return _serverName; }
}
}
public interface IAccumulator {
void Add(int sum);
}
public interface IAudit {
int Total();
}
[Synchronization()]
public class Account: ContextBoundObject,
IAccumulator, IAudit{
protected int sum = 0;
public void Add(int sum) {
this.sum += sum;
MyCallContextUserName userName =
(MyCallContextUserName)CallContext.GetData("UserName");
Console.WriteLine("UserName = " +
userName.UserName);
CallContext.SetData("ServerName",
new MyCallContextServerName());
}
public int Total() {
return this.sum;
}
}
public class AccountApp {
public static void Main() {
HttpChannel myChannel = new HttpChannel(8080);
ChannelServices.RegisterChannel(myChannel);
RemotingConfiguration.RegisterWellKnownServiceType {
typeof(Account), "Account",
WellKnownObjectMode.Singleton);
Console.WriteLine("Server is listening");
Console.ReadLine();
Console.WriteLine("Bye");
}
}
}
Относительно этого кода можно сделать следующие комментарии.
В методе Add наш сервер будет не только получать очередной вклад и зачислять его на счет, но и работать с контекстом вызова.
Во-первых, предполагается, что клиент перед вызовом метода Add добавил в контекст вызова свойство с именем UserName. Соответствующее значение содержит учетные данные пользователя, от имени которого было запущено клиентское приложение. Значение свойства UserName задается ссылкой на экземпляр класса
[Serializable]
public class MyCallContextUserName:
ILogicalThreadAffinative {…}
Из определения этого класса видно, что его экземпляры могут передаваться в контексте вызова за пределы текущего контекста, т. к. этот класс определяется с атрибутом сериализации и наследует интерфейс ILogicalThreadAffinative.
Конструктор данного класса
public MyCallContextUserName() {
_userName = Environment.UserName;
}
сохраняет в строковом поле _userName значение соответствующей переменной среды, получаемой как статическое свойство UserName класса Environment.
Используя свойство userName контекста вызова сервер в методе Add выясняет имя пользователя и выводит его на консоль:
MyCallContextUserName userName =
(MyCallContextUserName)CallContext.GetData("UserName");
Console.WriteLine("UserName = " +
userName.UserName);
Для доступа к нужному свойству используется статический метод GetData класса CallContext, которому в качестве параметра передается имя свойства. Полученное значение приводится к типу MyCallContextUserName.
Во-вторых, получив и выведя на консоль имя пользователя, сервер заканчивает выполнение метода Add, включая в контекст вызова свою информацию. Эту новую информацию сможет получить клиент, дождавшийся возврата из метода Add.
Итак, сервер добавляет в контекст вызова новое свойство с именем ServerName:
CallContext.SetData("ServerName",
new MyCallContextServerName()};
Класс MyCallContextS erverName определяется аналогично классу MyCallContextUserName.
Основная функциональность этого класса определяется его конструктором:
public MyCallContextServerName() {
_assembly = Assembly.GetExecutingAssembly();
_serverName = _assembly.FullName;
}
Здесь мы получаем ссылку на исполняемую сборку (т. е. на сборку сервера) и сохраняем в _serverName ее полное имя.
Остальная часть кода сервера не претерпела каких-либо изменений.
Клиент
using System; using MyServer;
using System. Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Net;
using System.Runtime.Remoting.Messaging;
public class MyApp {
public static void Main() {
HttpChannel с = new HttpChannel();
ChannelServices.RegisterChannel(c);
try {
Account a = (Account)Activator.GetObject(typeof(Account),
"http://localhost:8080/Account",
WellKnownObjectMode.Singleton);
CallContext.SetData("UserName",
new MyCallContextUserName());
a. Add(5);
Console.WriteLine("5 is sent to " +
((MyCallContextServerName)CallContext.GetData(
"ServerName")).ServerName);
Console.WriteLine("Total = " +a.Total());
}
catch(WebException e) {
Console.WriteLine(e.Message);
}
catch(Exception e) {
Console.WriteLine(e.Message);
}
finally!
Console.WriteLine("Bye");
}
}
}
Все отличие данного кода клиента от рассмотренных ранее примеров представлено в следующих строках
CallContext.SetData("UserName",
new MyCallContextUserName());
a. Add(5);
Console.WriteLine("5 is sent to " +
((MyCallContextServerName)CallContext.GetData (
"ServerName")).ServerName);
Перед вызовом метода Add клиент добавляет в контекст вызова уже рассмотренное свойство userName. В результате, при выполнении вызова Add, сервер получает доступ к учетным данным пользователя, от имени которого было запущено клиентское приложение, и может принимать решение о выполнении данного вызова.
По завершении вызова метода Add клиент получает из свойства контекста значение свойства serverName, добавленное в контекст вызова сервером при выполнении Add. В результате клиент получает информацию о сборке, содержащей код сервера, выполнившего
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Christine26 июнь 01:23 Сначала было тежеловта читать, но потом всё изменилось, я с удовольствием прочитала, спасибо за книгу. Я прочитала весь цикл... Опасное влечение - Полина Лоранс
-
Тамаринда21 июнь 12:33 Редко что-то цепляет, но тут было всё живое, жизненное, чувственное, сильное, читайте, не пожалеете о своём времени...... Хрупкая связь - Ольга Джокер
-
Гость Марина20 июнь 06:08 Книга очень понравилась, хотя и длинная. Героиня сильная личность. Да и герой не подкачал. ... Странная - Татьяна Александровна Шумкова