Подскажите, пжл, по какой причине может вылетать такое исключение:
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.
Здравствуйте, 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>Заранее спасибо
Пожалуйста.
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, Unforgiver, Вы писали:
U>Примерно так U>Вот это: V>> rIntegrator = new RemotingIntegrator(); U>Заменить на: U>rIntegrator = (RemotingIntegrator)Activator.GetObject(typeof(RemotingIntegrator), "http://localhost:4000/IntegratorURI");
И так пробовала написать, в результате получила то же исключение (будто бы не видит это поле типа ArrayList), при настройке с помощью конфигурационного файла наблюдается полностью аналогичная ситуация. Самое интересное состоит в том, что написала тестовый сервис и веб-сервис (простейшие), а также либу в которой содержится тип, используемый через ремотинг, проделала указанную в первом сообщении настройку .NET Remoting и создание объекта (в общем, этот тест полностью эмулирует сложившуюся ситуацию), всё работает странно как-то, может дело в настройках проекта, не знаю, что ещё можно предположить?
Здравствуйте, 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>Спасибо
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
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;
}
Здравствуйте, Unforgiver, Вы писали:
U>А может банально
U>ArrayList list = new ArrayList();
U>забыла ?
U>ИМХО, дело не в настройках ремотинга.
U>Проверь процедуру AddTask и все процедуры, которые из нее вызываются. Где-то есть неинициализированный объект.
U>Ну и таки создавай синглтон на клиенте через активатор.
Нет, вроде в конструкторе ремотинг-объекта прописала
Здравствуйте, Pavel M., Вы писали:
PM>Выделенное неправильно! Если Вы регистрируете объект как Singleton, он сам будет создан при обращении к ненму, Marshal служит для расшаривания уже созданных объектов, допустим, когда мы хотим создать объект с произовольным конструктором. Это раз. PM>Во-вторых, чтобы объект жил вечно, сделайте
На самом деле, если не делать Marshal, вообще всё перестаёт работать, сама не знаю почему. Проблема в действительности состоит в том, что объект на стороне клиента создаётся, но поле типа ArrayList оказывается почему-то null, хотя в конструкторе явно прописан new, при этом все остальные поля (например, типа int) и изменения, которые в них происходят на стороне сервера, видны на клиенте.
Здравствуйте, valia, Вы писали:
V>Здравствуйте, Pavel M., Вы писали:
PM>>Выделенное неправильно! Если Вы регистрируете объект как Singleton, он сам будет создан при обращении к ненму, Marshal служит для расшаривания уже созданных объектов, допустим, когда мы хотим создать объект с произовольным конструктором. Это раз. 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>Спасибо за совет
Пожалуйста
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, 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. Может что-то ещё надо прописать помимо этих вызовов?
Здравствуйте, 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>Спасибо
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
Здравствуйте, 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, может заработает странно только то, что тестовое приложение, содержащее абсолютно идентичные настройки ремотинга, с похожим ремотинг типом, работает
Здравствуйте, valia, Вы писали:
V>Голову уже сломала, с чем эта проблема может быть связана, попробую использовать протокол tcp, может заработает странно только то, что тестовое приложение, содержащее абсолютно идентичные настройки ремотинга, с похожим ремотинг типом, работает
Это действительно загадка
Я вот щас вспомнил. Сталкивался вот с чем:
В объекте-синглтоне есть поля. Например типа int и ArrayList.
Так вот если с клиента обращаться к этим полям, то int менялся, а ArrayList — нет. Я делал public методы, в которых работал с этим ArrayList-ом.
И вот еще. Я когда отлаживал приложение с ремотингом, в случае таких ошибок делал в лог запись после выполнения каждой строки. Тогда проще понять, что именно там Null.
Кстати, а http-протокол — обязательное условие ?
V>Ещё раз спасибо
Всё заканчивается плохо. Если что-то закончилось хорошо — значит оно еще не закончилось.
U>Это действительно загадка
U>Я вот щас вспомнил. Сталкивался вот с чем: U>В объекте-синглтоне есть поля. Например типа int и ArrayList.
U>Так вот если с клиента обращаться к этим полям, то int менялся, а ArrayList — нет. Я делал public методы, в которых работал с этим ArrayList-ом.
U>И вот еще. Я когда отлаживал приложение с ремотингом, в случае таких ошибок делал в лог запись после выполнения каждой строки. Тогда проще понять, что именно там Null.
U>Кстати, а http-протокол — обязательное условие ?
По сути метод AddTask, о котором я писала раньше, и есть public-метод, непосредственно к ArrayList на стороне клиента нигде не обращаюсь. Хорошая мысль с логами, надо взять на вооружение. По поводу протокола, в принципе никаких ограничений на используемый протокол не накладывалось, попробую использовать tcp, может заработает.
Здравствуйте, Unforgiver, Вы писали:
U>Я вот щас вспомнил. Сталкивался вот с чем: U>В объекте-синглтоне есть поля. Например типа int и ArrayList.
U>Так вот если с клиента обращаться к этим полям, то int менялся, а ArrayList — нет.
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class ArrayList : IList, ICollection,
IEnumerable, ICloneable
Здравствуйте, HowardLovekraft, Вы писали:
HL>Можно увидеть полную версию исходного кода для сервера и для клиента?
Боюсь, что абсолютно полную версию исходного кода, не получится увидеть, т.к. он достаточно большой, но участки, где непосредственно происходит работа с ремотинг, вполне:
сервер:
using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;
using System.Reflection;
using System.Configuration.Install;
using Remoting; //пространство имен, содержащее класс, наследуемый от MarshalByRefObjectusing 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();
}
// methodspublic 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 Remotingpublic 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();
Здравствуйте, 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.
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");
4. Ваша трассировка стека наводит на подозрения. Пожалуйста, приведите полную трассировку в режиме отладки. Должен быть серверный стек, клиентский стек и номера строчек для модулей, содержащих отладочную информаци.
Здравствуйте, 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