Настройка .NET Remoting
От: valia  
Дата: 29.10.08 12:29
Оценка:
Добрый день!

Подскажите, пжл, по какой причине может вылетать такое исключение:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.

Server stack trace:
at System.Runtime.Serialization.Formatters.Soap.ObjectWriter.WriteMembers(NameInfo memberNameInfo, NameInfo memberTypeNameInfo, Object memberData, WriteObjectInfo objectInfo, NameInfo typeNameInfo, WriteObjectInfo memberObjectInfo, Boolean isAttribute)
at System.Runtime.Serialization.Formatters.Soap.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String memberName, Type memberType, Object memberData, WriteObjectInfo memberObjectInfo, Boolean isAttribute)
at System.Runtime.Serialization.Formatters.Soap.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String[] memberNames, Type[] memberTypes, Object[] memberData, WriteObjectInfo[] memberObjectInfos)
at System.Runtime.Serialization.Formatters.Soap.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
at System.Runtime.Serialization.Formatters.Soap.ObjectWriter.Serialize(Object graph, Header[] inHeaders, SoapWriter serWriter)
at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers)
at System.Runtime.Remoting.Channels.CoreChannel.SerializeSoapMessage(IMessage msg, Stream outputStream, Boolean includeVersions)
at System.Runtime.Remoting.Channels.SoapClientFormatterSink.SerializeMessage(IMethodCallMessage mcm, ITransportHeaders& headers, Stream& stream)
at System.Runtime.Remoting.Channels.SoapClientFormatterSink.SyncProcessMessage(IMessage msg)

Ситуация такая: есть серверное приложение, в качестве которого выступает обычный сервис, есть клиент, реализованный в виде веб-сервиса, они взаимодействуют посредствам .NET Remoting. Соответсвенно на стороне сервера происходит настройка ремотинга:
HttpChannel channel = new HttpChannel(4000);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingIntegrator), "IntegratorURI", WellKnownObjectMode.Singleton);
RemotingIntegrator rIntegrator = new RemotingIntegrator();
RemotingServices.Marshal(rIntegrator, "IntegratorURI");
и на стороне клиента:
HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);
WellKnownClientTypeEntry remotetype = new WellKnownClientTypeEntry(typeof(Remoting.RemotingIntegrator),
"http://localhost:4000/IntegratorURI");
RemotingConfiguration.RegisterWellKnownClientType(remotetype);
rIntegrator = new RemotingIntegrator();
где
RemotingIntegrator — наследник MarshalByRefObject, одно из полей (public) класса RemotingIntegrator имеет тип ArrayList, также в RemotingIntegrator реализован метод AddTask, который отвечает за добаление элемента в этот ArrayList
Remoting — пространство имён, содержащее RemotingIntegrator.

Указанное исключение формируется при попытке вызова метода AddTask.

Заранее спасибо
Re: Настройка .NET Remoting
От: Unforgiver Россия  
Дата: 29.10.08 12:42
Оценка:
Здравствуйте, valia, Вы писали:

V>Добрый день!


V>Подскажите, пжл, по какой причине может вылетать такое исключение:

V>System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.

V>Ситуация такая: есть серверное приложение, в качестве которого выступает обычный сервис, есть клиент, реализованный в виде веб-сервиса, они взаимодействуют посредствам .NET Remoting. Соответсвенно на стороне сервера происходит настройка ремотинга:

V> HttpChannel channel = new HttpChannel(4000);
V> ChannelServices.RegisterChannel(channel);
V> RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingIntegrator), "IntegratorURI", WellKnownObjectMode.Singleton);
V> RemotingIntegrator rIntegrator = new RemotingIntegrator();
V> RemotingServices.Marshal(rIntegrator, "IntegratorURI");
V>и на стороне клиента:
V> HttpChannel channel = new HttpChannel();
V> ChannelServices.RegisterChannel(channel);
V> WellKnownClientTypeEntry remotetype = new WellKnownClientTypeEntry(typeof(Remoting.RemotingIntegrator),
V> "http://localhost:4000/IntegratorURI");
V> RemotingConfiguration.RegisterWellKnownClientType(remotetype);
Примерно так
Вот это:
V> rIntegrator = new RemotingIntegrator();
Заменить на:
rIntegrator = (RemotingIntegrator)Activator.GetObject(typeof(RemotingIntegrator), "http://localhost:4000/IntegratorURI");
V>где
V>RemotingIntegrator — наследник MarshalByRefObject, одно из полей (public) класса RemotingIntegrator имеет тип ArrayList, также в RemotingIntegrator реализован метод AddTask, который отвечает за добаление элемента в этот ArrayList
V>Remoting — пространство имён, содержащее RemotingIntegrator.

V>Указанное исключение формируется при попытке вызова метода AddTask.

Копай метод AddTask. Там что-то == null, вот и ловится эксепшн. При создании объекта на клиенте через new — ты создаешь его локальный экземпляр, а не ссылку на синглтон с сервера (на сколько я это понимаю).

V>Заранее спасибо

Пожалуйста.
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[2]: Настройка .NET Remoting
От: valia  
Дата: 29.10.08 13:09
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>Примерно так

U>Вот это:
V>> rIntegrator = new RemotingIntegrator();
U>Заменить на:
U>rIntegrator = (RemotingIntegrator)Activator.GetObject(typeof(RemotingIntegrator), "http://localhost:4000/IntegratorURI");

И так пробовала написать, в результате получила то же исключение (будто бы не видит это поле типа ArrayList), при настройке с помощью конфигурационного файла наблюдается полностью аналогичная ситуация. Самое интересное состоит в том, что написала тестовый сервис и веб-сервис (простейшие), а также либу в которой содержится тип, используемый через ремотинг, проделала указанную в первом сообщении настройку .NET Remoting и создание объекта (в общем, этот тест полностью эмулирует сложившуюся ситуацию), всё работает странно как-то, может дело в настройках проекта, не знаю, что ещё можно предположить?

Спасибо
Re[3]: Настройка .NET Remoting
От: Unforgiver Россия  
Дата: 29.10.08 14:00
Оценка:
Здравствуйте, valia, Вы писали:

V>Здравствуйте, Unforgiver, Вы писали:


U>>Примерно так

U>>Вот это:
V>>> rIntegrator = new RemotingIntegrator();
U>>Заменить на:
U>>rIntegrator = (RemotingIntegrator)Activator.GetObject(typeof(RemotingIntegrator), "http://localhost:4000/IntegratorURI");

V>И так пробовала написать, в результате получила то же исключение (будто бы не видит это поле типа ArrayList), при настройке с помощью конфигурационного файла наблюдается полностью аналогичная ситуация. Самое интересное состоит в том, что написала тестовый сервис и веб-сервис (простейшие), а также либу в которой содержится тип, используемый через ремотинг, проделала указанную в первом сообщении настройку .NET Remoting и создание объекта (в общем, этот тест полностью эмулирует сложившуюся ситуацию), всё работает странно как-то, может дело в настройках проекта, не знаю, что ещё можно предположить?


А может банально

ArrayList list = new ArrayList();

забыла ?

ИМХО, дело не в настройках ремотинга.

Проверь процедуру AddTask и все процедуры, которые из нее вызываются. Где-то есть неинициализированный объект.

Ну и таки создавай синглтон на клиенте через активатор.

V>Спасибо
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re: Настройка .NET Remoting
От: Pavel M. Россия  
Дата: 30.10.08 10:00
Оценка:
Здравствуйте, valia, Вы писали:

V>Добрый день!



V>Ситуация такая: есть серверное приложение, в качестве которого выступает обычный сервис, есть клиент, реализованный в виде веб-сервиса, они взаимодействуют посредствам .NET Remoting. Соответсвенно на стороне сервера происходит настройка ремотинга:

V> HttpChannel channel = new HttpChannel(4000);
V> ChannelServices.RegisterChannel(channel);
V> RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingIntegrator), "IntegratorURI", WellKnownObjectMode.Singleton);
V> RemotingIntegrator rIntegrator = new RemotingIntegrator();
V> RemotingServices.Marshal(rIntegrator, "IntegratorURI");
V>и на стороне клиента:
V> HttpChannel channel = new HttpChannel();
V> ChannelServices.RegisterChannel(channel);
V> WellKnownClientTypeEntry remotetype = new WellKnownClientTypeEntry(typeof(Remoting.RemotingIntegrator),
V> "http://localhost:4000/IntegratorURI");
V> RemotingConfiguration.RegisterWellKnownClientType(remotetype);
V> rIntegrator = new RemotingIntegrator();
V>где
V>RemotingIntegrator — наследник MarshalByRefObject, одно из полей (public) класса RemotingIntegrator имеет тип ArrayList, также в RemotingIntegrator реализован метод AddTask, который отвечает за добаление элемента в этот ArrayList
V>Remoting — пространство имён, содержащее RemotingIntegrator.

V>Указанное исключение формируется при попытке вызова метода AddTask.


V>Заранее спасибо


Выделенное неправильно! Если Вы регистрируете объект как Singleton, он сам будет создан при обращении к ненму, Marshal служит для расшаривания уже созданных объектов, допустим, когда мы хотим создать объект с произовольным конструктором. Это раз.
Во-вторых, чтобы объект жил вечно, сделайте


public override object InitializeLifetimeService()
{
   return null;
}


в своем объекте.
--------------------------
less think — do more
Re[4]: Настройка .NET Remoting
От: valia  
Дата: 30.10.08 11:18
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>А может банально


U>ArrayList list = new ArrayList();


U>забыла ?


U>ИМХО, дело не в настройках ремотинга.


U>Проверь процедуру AddTask и все процедуры, которые из нее вызываются. Где-то есть неинициализированный объект.


U>Ну и таки создавай синглтон на клиенте через активатор.


Нет, вроде в конструкторе ремотинг-объекта прописала

Спасибо за совет
Re[2]: Настройка .NET Remoting
От: valia  
Дата: 30.10.08 12:21
Оценка:
Здравствуйте, Pavel M., Вы писали:

PM>Выделенное неправильно! Если Вы регистрируете объект как Singleton, он сам будет создан при обращении к ненму, Marshal служит для расшаривания уже созданных объектов, допустим, когда мы хотим создать объект с произовольным конструктором. Это раз.

PM>Во-вторых, чтобы объект жил вечно, сделайте


PM>
PM>public override object InitializeLifetimeService()
PM>{
PM>   return null;
PM>}

PM>


PM>в своем объекте.


На самом деле, если не делать Marshal, вообще всё перестаёт работать, сама не знаю почему. Проблема в действительности состоит в том, что объект на стороне клиента создаётся, но поле типа ArrayList оказывается почему-то null, хотя в конструкторе явно прописан new, при этом все остальные поля (например, типа int) и изменения, которые в них происходят на стороне сервера, видны на клиенте.

Спасибо за совет
Re[3]: Настройка .NET Remoting
От: Unforgiver Россия  
Дата: 30.10.08 12:46
Оценка:
Здравствуйте, valia, Вы писали:

V>Здравствуйте, Pavel M., Вы писали:


PM>>Выделенное неправильно! Если Вы регистрируете объект как Singleton, он сам будет создан при обращении к ненму, Marshal служит для расшаривания уже созданных объектов, допустим, когда мы хотим создать объект с произовольным конструктором. Это раз.

PM>>Во-вторых, чтобы объект жил вечно, сделайте


PM>>
PM>>public override object InitializeLifetimeService()
PM>>{
PM>>   return null;
PM>>}

PM>>


PM>>в своем объекте.


V>На самом деле, если не делать Marshal, вообще всё перестаёт работать, сама не знаю почему. Проблема в действительности состоит в том, что объект на стороне клиента создаётся, но поле типа ArrayList оказывается почему-то null, хотя в конструкторе явно прописан new, при этом все остальные поля (например, типа int) и изменения, которые в них происходят на стороне сервера, видны на клиенте.


Без маршала активатором создавай и на сервере и на клиенте.

Сервер:

RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyObject), "ObjectName", WellKnownObjectMode.Singleton);
string objURI = "tcp://localhost:4444/ApplicationName/ObjectName"; // (ObjectName - тот же самый соответственно)
MyObject obj = (MyObject)Activator.GetObject(typeof(MyObject), objURI); // Вот тут вызывается конструктор синглтона


Клиент:

string objURI = "tcp://remotehost:4444/ApplicationName/ObjectName"; // Тоже самое, что и на сервере, только хост может быть другим
MyObject obj = (MyObject)Activator.GetObject(typeof(MyObject), objURI);


Ну и про InitializeLifetimeService не забывай. В .NET 1.1 он по дефолту был = null (т.е. время жизни синглтона бесконечно), в 2.0 != null, т.е. конечно, и довольно маленькое (точно не помню, какое)

V>Спасибо за совет

Пожалуйста
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[4]: Настройка .NET Remoting
От: valia  
Дата: 30.10.08 13:20
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>Без маршала активатором создавай и на сервере и на клиенте.


U>Сервер:


U>
U>RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyObject), "ObjectName", WellKnownObjectMode.Singleton);
U>string objURI = "tcp://localhost:4444/ApplicationName/ObjectName"; // (ObjectName - тот же самый соответственно)
U>MyObject obj = (MyObject)Activator.GetObject(typeof(MyObject), objURI); // Вот тут вызывается конструктор синглтона
U>


U>Клиент:


U>
U>string objURI = "tcp://remotehost:4444/ApplicationName/ObjectName"; // Тоже самое, что и на сервере, только хост может быть другим
U>MyObject obj = (MyObject)Activator.GetObject(typeof(MyObject), objURI); 
U>


Попробовала, но при обращении к полю моего ремотинг-объекта на стороне сервера получила исключение: Tcp channel protocol violation: expecting preamble. Может что-то ещё надо прописать помимо этих вызовов?

Спасибо
Re[5]: Настройка .NET Remoting
От: Unforgiver Россия  
Дата: 30.10.08 14:14
Оценка:
Здравствуйте, valia, Вы писали:

V>Попробовала, но при обращении к полю моего ремотинг-объекта на стороне сервера получила исключение: Tcp channel protocol violation: expecting preamble. Может что-то ещё надо прописать помимо этих вызовов?


Создать каналы надо. Вот так:

Сервер

BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider();
bp.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

TcpServerChannel    tChannel = new TcpServerChannel("ChannelName", 4444, bp); // 4444 - порт, на который потом будешь вешать синглтон. Имя канала - любое
ChannelServices.RegisterChannel(tChannel, false);


Клиент (вроде этот канал прописывать не обязательно. Я давно читал про это, щас уже забыл — код взял из своего старого приложения )

BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider();
bp.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

TcpServerChannel tChannel = new TcpServerChannel("", 0, bp);
ChannelServices.RegisterChannel(tChannel, false);


Если не будет работать, еще поковыряю код — может еще что-то всплывёт.


V>Спасибо
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[6]: Настройка .NET Remoting
От: valia  
Дата: 30.10.08 14:46
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>Создать каналы надо. Вот так:


U>Сервер


U>
U>BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider();
U>bp.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

U>TcpServerChannel    tChannel = new TcpServerChannel("ChannelName", 4444, bp); // 4444 - порт, на который потом будешь вешать синглтон. Имя канала - любое
U>ChannelServices.RegisterChannel(tChannel, false);
U>


U>Клиент (вроде этот канал прописывать не обязательно. Я давно читал про это, щас уже забыл — код взял из своего старого приложения )


U>
U>BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider();
U>bp.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

U>TcpServerChannel tChannel = new TcpServerChannel("", 0, bp);
U>ChannelServices.RegisterChannel(tChannel, false);
U>


U>Если не будет работать, еще поковыряю код — может еще что-то всплывёт.


Я вроде создаю каналы, только поскольку использую протокол http, а не tcp, то это делается немного по-другому (судя по тому, что пишут в литературе на эту тему, здесь должно быть всё правильно):
на сервере:
int port = 4000;
HttpChannel channel = new HttpChannel(port);
ChannelServices.RegisterChannel(channel);

на клиенте:
HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);


Голову уже сломала, с чем эта проблема может быть связана, попробую использовать протокол tcp, может заработает странно только то, что тестовое приложение, содержащее абсолютно идентичные настройки ремотинга, с похожим ремотинг типом, работает

Ещё раз спасибо
Re[7]: Настройка .NET Remoting
От: Unforgiver Россия  
Дата: 30.10.08 14:59
Оценка:
Здравствуйте, valia, Вы писали:

V>Голову уже сломала, с чем эта проблема может быть связана, попробую использовать протокол tcp, может заработает странно только то, что тестовое приложение, содержащее абсолютно идентичные настройки ремотинга, с похожим ремотинг типом, работает


Это действительно загадка

Я вот щас вспомнил. Сталкивался вот с чем:
В объекте-синглтоне есть поля. Например типа int и ArrayList.

Так вот если с клиента обращаться к этим полям, то int менялся, а ArrayList — нет. Я делал public методы, в которых работал с этим ArrayList-ом.

И вот еще. Я когда отлаживал приложение с ремотингом, в случае таких ошибок делал в лог запись после выполнения каждой строки. Тогда проще понять, что именно там Null.

Кстати, а http-протокол — обязательное условие ?

V>Ещё раз спасибо
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Re[8]: Настройка .NET Remoting
От: valia  
Дата: 31.10.08 07:40
Оценка:
Здравствуйте, Unforgiver, Вы писали:


U>Это действительно загадка


U>Я вот щас вспомнил. Сталкивался вот с чем:

U>В объекте-синглтоне есть поля. Например типа int и ArrayList.

U>Так вот если с клиента обращаться к этим полям, то int менялся, а ArrayList — нет. Я делал public методы, в которых работал с этим ArrayList-ом.


U>И вот еще. Я когда отлаживал приложение с ремотингом, в случае таких ошибок делал в лог запись после выполнения каждой строки. Тогда проще понять, что именно там Null.


U>Кстати, а http-протокол — обязательное условие ?


По сути метод AddTask, о котором я писала раньше, и есть public-метод, непосредственно к ArrayList на стороне клиента нигде не обращаюсь. Хорошая мысль с логами, надо взять на вооружение. По поводу протокола, в принципе никаких ограничений на используемый протокол не накладывалось, попробую использовать tcp, может заработает.

Спасибо
Re: Настройка .NET Remoting
От: HowardLovekraft  
Дата: 31.10.08 07:50
Оценка:
Можно увидеть полную версию исходного кода для сервера и для клиента?
Re[8]: Настройка .NET Remoting
От: HowardLovekraft  
Дата: 31.10.08 07:53
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>Я вот щас вспомнил. Сталкивался вот с чем:

U>В объекте-синглтоне есть поля. Например типа int и ArrayList.

U>Так вот если с клиента обращаться к этим полям, то int менялся, а ArrayList — нет.


[SerializableAttribute]
[ComVisibleAttribute(true)]
public class ArrayList : IList, ICollection, 
    IEnumerable, ICloneable

Выделенное на мысли не наводит?
Re[2]: Настройка .NET Remoting
От: valia  
Дата: 31.10.08 12:09
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Можно увидеть полную версию исходного кода для сервера и для клиента?


Боюсь, что абсолютно полную версию исходного кода, не получится увидеть, т.к. он достаточно большой, но участки, где непосредственно происходит работа с ремотинг, вполне:
сервер:
using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;
using System.Reflection;
using System.Configuration.Install;
using Remoting; //пространство имен, содержащее класс, наследуемый от MarshalByRefObject
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;

namespace Integrator
{
    [System.ComponentModel.RunInstallerAttribute(true)]
    public class InstallService : System.Configuration.Install.Installer
    {
        private System.ServiceProcess.ServiceInstaller _SInst = new ServiceInstaller();
        private System.ServiceProcess.ServiceProcessInstaller _SPInst = new ServiceProcessInstaller();

        public InstallService()
        {
            _SPInst.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
            _SInst.DisplayName = "Metacluster integrator";
            _SInst.ServiceName = "Metacluster integrator";
            _SInst.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
            this.Installers.Add(_SPInst);
            this.Installers.Add(_SInst);
        }


        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            System.ServiceProcess.ServiceController _sc = new ServiceController("Metacluster integrator", System.Environment.MachineName);
            if (_sc.CanStop) _sc.Stop();
            _sc.Close();
            base.Uninstall(savedState);
        }
    }

    static class Program
    {
        static bool m_test;
        static bool m_install;
        static bool m_uninstall;

        static int ShowHelp()
        {
            System.Console.Write("Usage: integrator.exe [parameter1]\n\n");

            System.Console.Write("Parameter1:\n");
            System.Console.Write("-install - install service\n");
            System.Console.Write("-uninstall - uninstall service\n");
            System.Console.Write("-test - run the program in test mode\n\n");
            return 1;
        }

        static void Main(string[] args)
        {
          System.IO.Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            if (!Utilities.ProcessCommandArguments(args, ref m_test, ref m_install, ref m_uninstall))
            {
                ShowHelp();
                return;
            }

            if (m_install)
            {
                try
                {
                    ManagedInstallerClass.InstallHelper(
                        new string[] { Assembly.GetExecutingAssembly().Location });
                }
                catch(System.Exception ex)
                {
                    System.Console.WriteLine(ex.Message);
                }
                return;
            }

            if (m_uninstall)
            {
                try
                {
                    ManagedInstallerClass.InstallHelper(
                        new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                }
                catch (System.Exception ex)
                {
                    System.Console.WriteLine(ex.Message);
                }
                return;
            }

            if (m_test)
            {
                RemotingIntegrator rIntegrator = RemotingIntegrator.ConfigureRemotingIntegrator();//статический метод, в котором происходит                                                                                                            //конфигурирование .NET Remoting
                Metacluster.Task task = new Metacluster.Task(); //Task - сериализуемый тип, содержащийся в пространстве Metacluster
                rIntegrator.AddTask(task); //метод, в котором осуществляется добавление в ArrayList
                rIntegrator.field = 100000;//целочисленное поле
                Console.WriteLine(rIntegrator.field);
                Console.ReadLine();
                return;
            }

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] { new IntegratorService() };

            ServiceBase.Run(ServicesToRun);
        }
    }
}


клиент:
using System.Configuration;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using Remoting;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System;
using System.Collections;
 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1),
WebService(Namespace = "http://gw-114.unn.ac.ru/metaclusterws/")]
public class Service : System.Web.Services.WebService
{
    static RemotingIntegrator rIntegrator;

    static Service()
    {
        HttpChannel channel = new HttpChannel();
        ChannelServices.RegisterChannel(channel);
        object remoteObj = Activator.GetObject(typeof(Remoting.RemotingIntegrator),
                                               "http://localhost:4000/IntegratorURI");
        rIntegrator = (RemotingIntegrator)remoteObj;
    }

    public Service()
    {
    }

    [WebMethod]
    public string AddTest()
    {
        Metacluster.Task task = new Metacluster.Task();
        rIntegrator.AddTask(task);
        return ((Metacluster.Task)rIntegrator.m_RTaskPool[0]).m_ActiveDir;
    }
}

пространство имён Remoting:
using System;
using System.Collections.Generic;
using System.Text;
using Metacluster;
using System.Collections;

namespace Remoting
{
  public class Remoting : MarshalByRefObject
  {
    public ArrayList m_RTaskPool;
    public int field;

    public Remoting() : base() 
    {
        m_RTaskPool = new ArrayList();
    }

    // methods
    public bool AddTask(object task)
    {
      bool resAdd = false;
      int index = -1;
      lock (m_RTaskPool)
      {
        index = m_RTaskPool.Add(task);
      }
      if (index >= 0) resAdd = true;
      return resAdd;
    }

    public override object InitializeLifetimeService()
    {
      return null;
    }

  }
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;


namespace Remoting
{
  public class RemotingIntegrator : Remoting
  {
    public RemotingIntegrator() : base() { }

    // Configure infrastructure .NET Remoting
    public static RemotingIntegrator ConfigureRemotingIntegrator()
    {
        int port = 4000;
        HttpChannel channel = new HttpChannel(port);
        ChannelServices.RegisterChannel(channel);
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingIntegrator), "IntegratorURI", WellKnownObjectMode.Singleton);
        RemotingIntegrator rIntegrator = new RemotingIntegrator();
        RemotingServices.Marshal(rIntegrator, "IntegratorURI");
        return rIntegrator;
    }
  }
}


пространство имён Metacluster:
task.h:
#ifndef __TASK_H__
#define __TASK_H__

using namespace System;

namespace Metacluster
{
[Serializable]
public ref class Task
{
public:
Task(void);
Task(System::String ^_user, System::String ^_name, System::String ^_module_name,
System::String ^ _output_redir, int _priority, Int64 _id, int _user_id, int _nproc, System::String ^_cmd,
Int64 _mode);
Task(const Task ^task);
virtual ~Task();

Task ^operator=(const Task ^task);
System::String ^ Pack();

Int64 m_Id;
Int64 m_Mode;
Int64 m_CCSJobId;

System::String ^m_Name;
System::String ^m_User;
System::String ^m_ModuleName;
System::String ^m_CommandLine;
System::String ^m_OutputRedirection;

int m_UserId;
int m_Priority;
int m_Nproc;

System::String ^m_ActiveDir;
System::Array ^m_BusyMachines;

System::DateTime ^m_StartTime;
System::DateTime ^m_StopTime;
System::DateTime ^m_AddTime;
System::DateTime ^m_DeleteTime;

bool m_IsStoppingRequest;

///If task was submitted to CCS but not started
///it's state is RUNNING but m_queuedInCCS is true
bool m_queuedInCCS;

protected:

private:

};
}
#endif

task.cpp:
#include "stdafx.h"
#include "time.h"
#include <stdlib.h>
#include <memory.h>
#include "Task.h"

using namespace System;
using namespace System::Xml;
using namespace Metacluster;

Task::Task(void)
{
m_OutputRedirection = "";
m_User = "";
m_Name = "";
m_ModuleName = "";
m_Priority = 0;
GenerateId();
m_CCSJobId = 0;
m_UserId = 0;
m_Nproc = 1;
m_CommandLine = "";

m_ActiveDir = ".\\";

m_StartTime = gcnew DateTime(0);
m_StopTime = gcnew DateTime(0);
m_AddTime = gcnew DateTime(0);
m_DeleteTime = gcnew DateTime(0);

m_IsStoppingRequest = false;
m_queuedInCCS = false;
};


Task::Task(System::String ^_user, System::String ^_name, System::String ^_module_name,
System::String ^ _output_redir, int _priority, Int64 _id, int _user_id, int _nproc, System::String ^_cmd,
Int64 _mode)
{
m_User = _user;
m_Name = _name;
m_ModuleName = _module_name;
m_OutputRedirection = _output_redir;
m_Priority = _priority;
m_CCSJobId = 0;
m_Id = _id;
m_UserId = _user_id;
m_Nproc = _nproc;
m_CommandLine = _cmd;
m_State = _state;

m_Mode = _mode;

m_ActiveDir = ".\\";

m_StartTime = gcnew DateTime(0);
m_StopTime = gcnew DateTime(0);
m_AddTime = gcnew DateTime(0);
m_DeleteTime = gcnew DateTime(0);
};

Task::Task(const Task ^task): m_BusyMachines(task->m_BusyMachines)
{
m_User = task->m_User;
m_Name = task->m_Name;
m_ModuleName = task->m_ModuleName;
m_OutputRedirection = task->m_OutputRedirection;
m_Priority = task->m_Priority;
m_UserId = task->m_UserId;
m_Id = task->m_Id;
m_CCSJobId = task->m_CCSJobId;
m_Nproc = task->m_Nproc;
m_CommandLine = task->m_CommandLine;
m_ActiveDir = task->m_ActiveDir;
m_StartTime = task->m_StartTime;
m_StopTime = task->m_StopTime;
m_AddTime = task->m_AddTime;
m_DeleteTime = task->m_DeleteTime;
m_IsStoppingRequest = task->m_IsStoppingRequest;
}

Task::~Task()
{
}


Task ^Task::operator=(const Task ^task)
{
m_User = task->m_User;
m_Name = task->m_Name;
m_ModuleName = task->m_ModuleName;
m_OutputRedirection = task->m_OutputRedirection;
m_Priority = task->m_Priority;
m_UserId = task->m_UserId;
m_Id = task->m_Id;
m_CCSJobId = task->m_CCSJobId;
m_Nproc = task->m_Nproc;
m_CommandLine = task->m_CommandLine;
m_ActiveDir = task->m_ActiveDir;
m_StartTime = task->m_StartTime;
m_StopTime = task->m_StopTime;
m_AddTime = task->m_AddTime;
m_DeleteTime = task->m_DeleteTime;
m_BusyMachines = task->m_BusyMachines;
m_IsStoppingRequest = task->m_IsStoppingRequest;
m_queuedInCCS = task->m_queuedInCCS;
return this;
}

Вроде бы остальное не используется...

Заранее спасибо
Re[9]: Настройка .NET Remoting
От: valia  
Дата: 31.10.08 12:27
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>
HL>[SerializableAttribute]
HL>[ComVisibleAttribute(true)]
HL>public class ArrayList : IList, ICollection, 
HL>    IEnumerable, ICloneable
HL>

HL>Выделенное на мысли не наводит?

Если не ошибаюсь, то это говорит о том, что объекты данного типа сериализуемы, не так?
Re[4]: Настройка .NET Remoting
От: valia  
Дата: 31.10.08 13:31
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>Без маршала активатором создавай и на сервере и на клиенте.


U>Сервер:


U>
U>RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyObject), "ObjectName", WellKnownObjectMode.Singleton);
U>string objURI = "tcp://localhost:4444/ApplicationName/ObjectName"; // (ObjectName - тот же самый соответственно)
U>MyObject obj = (MyObject)Activator.GetObject(typeof(MyObject), objURI); // Вот тут вызывается конструктор синглтона
U>


U>Клиент:


U>
U>string objURI = "tcp://remotehost:4444/ApplicationName/ObjectName"; // Тоже самое, что и на сервере, только хост может быть другим
U>MyObject obj = (MyObject)Activator.GetObject(typeof(MyObject), objURI); 
U>


U>Ну и про InitializeLifetimeService не забывай. В .NET 1.1 он по дефолту был = null (т.е. время жизни синглтона бесконечно), в 2.0 != null, т.е. конечно, и довольно маленькое (точно не помню, какое)


У меня возник вопрос при реализации ремотинг с использованием протокола tcp, ApplicationName — это ведь имя исполняемого файла сервера (в моём случае сервиса), так ведь? или что-то другое, потому что если это так, то у меня на сервере при обращении к ремотинг-объекту формируется исключение Requested Service not found, а если его не указывать, то на сервере нельзя работать с ArrayList, а на клиенте в этом случае — вообще чё-то этого объекта нет, пишет исключение при обращении System.NullReferenceException: Object reference not set to an instance of an object.
Re[3]: Настройка .NET Remoting
От: HowardLovekraft  
Дата: 31.10.08 14:00
Оценка:
1. Чем обусловлен выбор HttpChannel, а не пары HttpServerChannel и HttpClientChannel? Это сделано сознательно?
2. Метод ChannelServices.RegisterChannel(IChannel) — устаревший. Его использование чем-то обусловлено?
3. Вот это:
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingIntegrator), "IntegratorURI", WellKnownObjectMode.Singleton);
RemotingIntegrator rIntegrator = new RemotingIntegrator();
RemotingServices.Marshal(rIntegrator, "IntegratorURI");

как минимум бессмысленно. Зарегистрируйте свой tracking handler
using System.Runtime.Remoting.Services;

....

    internal class MyTrackingHanlder : ITrackingHandler
    {
        #region ITrackingHandler Members

        public void DisconnectedObject(object obj)
        {
            Console.WriteLine("Disconnected obj: {0}", obj.GetType());
        }

        public void MarshaledObject(object obj, ObjRef or)
        {
            Console.WriteLine("Marshalled obj: {0}, URI: {1}", obj.GetType(), or.URI);
        }

        public void UnmarshaledObject(object obj, ObjRef or)
        {
            Console.WriteLine("UnMarshalled obj: {0}, URI: {1}", obj.GetType(), or.URI);
        }

        #endregion
    }

...
public static RemotingIntegrator ConfigureRemotingIntegrator()
{
...
    TrackingServices.RegisterTrackingHandler(new MyTrackingHanlder());
...
}

и посмотрите на маршаллинг объектов. В вашем случае на ремоутинг-вызовы будет отвечать объект, созданный здесь:
RemotingIntegrator rIntegrator = new RemotingIntegrator();
RemotingServices.Marshal(rIntegrator, "IntegratorURI");

Так что либо эти две строчки, либо
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingIntegrator), "IntegratorURI", WellKnownObjectMode.Singleton);


4. Ваша трассировка стека наводит на подозрения. Пожалуйста, приведите полную трассировку в режиме отладки. Должен быть серверный стек, клиентский стек и номера строчек для модулей, содержащих отладочную информаци.
Re[2]: Настройка .NET Remoting
От: HowardLovekraft  
Дата: 31.10.08 14:04
Оценка:
Здравствуйте, Unforgiver, Вы писали:

U>При создании объекта на клиенте через new — ты создаешь его локальный экземпляр, а не ссылку на синглтон с сервера (на U>сколько я это понимаю).


The only difference between Activator.GetObject and new is that the former allows you to specify a URL as a parameter, and the latter obtains the URL from the configuration

Вы уверены, что понимаете это?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.