Пытаюсь разобраться с .Net Remoting

 
0
 
.NET
ava
compaq | 21.10.2007, 13:50
В общем, проблема в следующем. Есть программа клиент сервер смысл, который таков на сервер генерирует очки, которые получает клиент. После того как клиент получил очки он усыпляет на определённое время потом другой клиент запрашивает очки и он тоже усыпляется так происходит до тех пор пока на сервере не закончатся очки. Проблема вот в чём при попытке вызвать метод на сервере в клиенте вываливается ошибка что
meaning = obj.MyStrimng();
затребованная служба не найдена от чего так происходит

Код клиента

public partial class Form1 : Form
{
int meaning;
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
ChannelServices.RegisterChannel(new TcpClientChannel());
Work obj = (Work)Activator.GetObject(
typeof(Work), "tcp://localhost:8086/Hi");

for (int i = 0; i < 5; i++)
{
meaning = obj.MyStrimng();
if (meaning != 101)
{
listBox1.Items.Add(Convert.ToString(meaning));
Thread.Sleep(meaning * 5000);
}
else
{
listBox1.Items.Add("На сервере больше не осталось очков Game over %-)");
}

}

Код сервера

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
TcpServerChannel tcpChannel = new TcpServerChannel(8086);
ChannelServices.RegisterChannel(tcpChannel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Work), "Wor", WellKnownObjectMode.Singleton);
}
}

Код библиотеки

public class Work : System.MarshalByRefObject
{
int ran;
int mark = 100;
Random random = new Random();
public int MyStrimng()
{
ran = random.Next(1, 10);
if (ran >= mark)
{
return mark - ran;
}
else
{
return 101;
}
}
}



P.S.Все библиотеки подлючены
Comments (6)
ava
Baa | 21.10.2007, 17:19 #
Посмотри, как ты обозвал объект на сервере и как ты к нему пытаешься обратиться.
Подсказка: "tcp://localhost:8086/Hi" в эту строку пишут не абы-чего.
п.с. М$ рекомендует обзывать все объекты с .rem
ava
Мурлыкатам_ | 22.10.2007, 07:11 #
Цитата

  RemotingConfiguration.RegisterWellKnownServiceType(typeof(Work), "Wor", WellKnownObjectMode.Singleton);


В сервере:
Упущен форматтер: RemotingConfiguration.RegisterWellKnownServiceType(typeof(Work), "Wor.tcp", WellKnownObjectMode.Singleton);

Цитата


ChannelServices.RegisterChannel(new TcpClientChannel());


Не знаю точно так ли должно это делаться, но обычно делается в клиенте так (в учебных примерах smile ):

TcpChannel c = new TcpChannel();
ChannelServices.RegisterChannel©;

Цитата


Work obj = (Work)Activator.GetObject(

typeof(Work), "tcp://localhost:8086/Hi");



Тоже нужно в клиенте указать тип форматера, через который будут отправляться сообщения серверу:
"tcp://localhost:8086/Hi.tcp"

Цитата


Заключительным элементом головоломки удаленного взаимодействия дотНет является форматтер. Типы HttpChannel and TcpChannel используют свои внутренние форматтеры, задачей которых является перевод объекта сообщения в термины соответствующего протокола, Как уже говорилось TcpChannel использует BinaryFormatter, в то время как HttpChannel использует функциональные возможности типа SoapFormatter. .... После создания форматированного сообщения оно передается в канал, по которому в конце концов достигает целевого домена приложения. Там это сообщение преобразуется из специфических терминов протоколо обратнов в термины дотНет, после чего элемент, который называется диспетчер, вызывает нужный метод удаленного объекта. (Так говорит нам Троелсен)

ava
Baa | 22.10.2007, 11:01 #
Цитата


TcpChannel c = new TcpChannel();

ChannelServices.RegisterChannel(с);


А как ты думаешь, что было написано в его коде?


Цитата


Тоже нужно в клиенте указать тип форматера, через который будут отправляться сообщения серверу:

"tcp://localhost:8086/Hi.tcp"


Ну, указали и что дальше? Работать это всё равно не будет т.к. задан неверный URI. Мы пытаемся затребовать объект Hi, хотя на сервере он на самом деле "Wor".

Цитата


Заключительным элементом головоломки удаленного взаимодействия дотНет является форматтер. Типы HttpChannel and TcpChannel используют свои внутренние форматтеры, задачей которых является перевод объекта сообщения в термины соответствующего протокола, Как уже говорилось TcpChannel использует BinaryFormatter, в то время как HttpChannel использует функциональные возможности типа SoapFormatter. .... После создания форматированного сообщения оно передается в канал, по которому в конце концов достигает целевого домена приложения. Там это сообщение преобразуется из специфических терминов протоколо обратнов в термины дотНет, после чего элемент, который называется диспетчер, вызывает нужный метод удаленного объекта. (Так говорит нам Троелсен)


Это тут к чему?

Вообще, по всему этому есть хорошая книга.
Microsoft .NET Framework 2.0 Distributed Application Development (в рамках экзамена 70-529).
ava
compaq | 22.10.2007, 13:26 #
Всем спасибо, smile Какой же я не внимательный исправил на серваке а в клиенте забыл smile smile smile
Я тут всё поправил но возникла новая проблемка :biggrin smile3 Хотя я понимаю что она глупая но раньше я с этим не сталкивался а сейчас не как не могу найти ответ. В обшем она заключается в следуюшем
Мне нужно передать в обработчик событий таймера obj

public partial class Form1 : Form
{
int meaning;
string value;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
value = Convert.ToString(textBox1.Text);
value += ":8086/Hi";
value = "tcp://" + value;
Work obj = (Work)Activator.GetObject(typeof(Work), value);
timer1.Interval = 1000;
timer1.Enabled = true;
}

private void timer1_Tick(object sender, EventArgs e)
{
meaning = obj.MyStrimng();// Так как сдесь компилятор пишет вполне оправдано что он не может найти obj
if (meaning != 101)
{
listBox1.Items.Add(Convert.ToString(meaning));
timer1.Interval = meaning * 100;
}
else
{
listBox1.Items.Add("На сервере больше не осталось очков Game over %-)");
timer1.Enabled = false;
}
}
}

Но как это сделать я не могу найти
ava
Baa | 22.10.2007, 22:27 #
Вынеси локальную переменную obj из функции, сделай её членом класса Form1 как meaning и value.
бтв, я, конечно, понимаю, что это занудство, но складывать строки таким образом - моветон. String.Format || StringBuilder || String.Join.
ava
compaq | 26.10.2007, 22:45 #
Можно мне задать ещё один вопрос. smile
В общем, проблема в следующем. Мне нужно в гуи сервера ввести несколько полей, которые бы передавали значения в класс. Как это можно реализовать?

Сервер

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{

}

private void Form1_Load(object sender, EventArgs e)
{
TcpServerChannel tcpChannel = new TcpServerChannel(8086);
ChannelServices.RegisterChannel(tcpChannel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Work), "Hi", WellKnownObjectMode.Singleton);

foreach (System.Net.IPAddress ip in
System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName()).AddressList)
{ label1.Text = Convert.ToString(ip); }
}
}


Библиотека

public class Work : System.MarshalByRefObject
{
int ran;
public int mark = 100;
Random random = new Random();
public int MyStrimng()
{
ran = random.Next(1, 10);
if (ran <= mark)
{
mark = mark - ran;
return mark;
}
else
{
return 101;
}
}
}


То есть допустим к примеру в сервере ввести текст бокс которые будет присваивать значение переменной mark из библиотеки.
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit