Достать нынче дешевый Windows хостинг легко и дорого, а создавать Silverlight клиент-серверные приложения хочется. Собственно, тем и занимаюсь последнее время. Так как Linux хостинг у меня уже есть, решил его использовать для этих целей.
Итак, опишем задачу. Silverlight приложение позволяет вводить текст и отсылать его на сервер, где эти данные обрабатываются PHP скриптом – вычисляется MD5 хеш, который отсылается клиенту, полученные данные отображаются в ТеxtBox.
Примечание: В Silverlight 4 RC функций по вычислению MD5 хеша все еще нет, хотя при непродолжительном поиске можно найти готовые классы.
Создание клиента
Для начала создадим стандартный проект Silverlight Application. Добавим в главную и единственную форму: TextBox для ввода отсылаемых данных, кнопку, которая инициирует отсылку и TextBlock который и будет отображать ответ, открываем MainPage.xaml и добавляем следующий текст:
<UserControl x:Class="SilverlightClient.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White"
Width="400" Height="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90" />
<ColumnDefinition Width="285*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="72*" />
<RowDefinition Height="50" />
<RowDefinition Height="25" />
<RowDefinition Height="153*" />
</Grid.RowDefinitions>
<TextBlock Text="Данные:" Grid.Row="1" Grid.Column="0"
VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBlock Text="MD5:" Grid.Row="2" Grid.Column="0"
VerticalAlignment="Center" HorizontalAlignment="Right"/>
<TextBox x:Name="inputText" Grid.Column="1" Grid.Row="1"
BorderBrush="Black" BorderThickness="1"
TextWrapping="Wrap"/>
<TextBox x:Name="ReceivedText" Text="Empty" Grid.Column="1" Grid.Row="2"
BorderBrush="Black" BorderThickness="1"/>
<Button x:Name="SendButton" Content="Отправить" Width="100" Height="25"
HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="3" Grid.Column="1"
Click="SendButton_Click"/>
</Grid>
</UserControl>
С разметкой формы закончили, перейдем к разработке клиентской логики.
- По нажатию кнопки «SendButton» отправляем текст из текстового поля «inputText».
- При получении данных отображаем их в поле «ReceivedText».
Двойной клик мыши по кнопке «SendButton» автоматически создаст обработчик события Click, остается только его наполнить смыслом:
// Если поле ввода пустое, то ничего не делаем
if (String.IsNullOrEmpty(inputText.Text)) return;
// Создаем экземпляр класса WebClient
var client = new WebClient();
// Адрес серверной части
var uri = new Uri("http://localhost/index.php");
// задаем обработчик события UploadStringCompleted
client.UploadStringCompleted += new UploadStringCompletedEventHandler(UploadStringCompleted);
// передаем данные на сервер
client.UploadStringAsync(uri, inputText.Text);
Чуть выше мы реализовали метод для отправки данных, и там же подписались на событие UploadStringCompleted. Это событие возникает когда данные отправлены и получен ответ от сервера, для проверки этого достаточно добавить в index.php команду sleep(10), это добавить паузу 10 секунд в обработку запроса. В методе
void UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
мы и реализуем логику:
void UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
if (e.Error == null)
{
ReceivedText.Text = e.Result;
}
}
А логика простая, если не возникло ошибок, то отображаем содержимое в ReceivedText.
Создание сервера
Получили код который отсылает данные на сервер. Серверную часть напишем на PHP, потому как WCF сервис в Apache ну никак не захостится. Создаем файл index.php со следующим содержимым:
<?php
$data = file_get_contents('php://input');
if ($data) {
echo md5($data);
}
else {
echo "";
}
?>
Тут все просто для PHP программиста, а вот для меня этот код стоил 2 часов времени, если не больше. Дело в том, что отсылая данные на сервер и не указывая дополнительных заголовков, они не попадают в массив $_POST. Добраться до них можно только таким способом – file_get_contents(‘php://input’). По полученным данным вычисляется хеш md5 и возвращается обратно.
Примечание
Для того чтобы клиентское приложение могло обращаться к серверу рядом с index.php нужно создать файл crossdomain.xml со следующим содержимым:
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-http-request-headers-from domain="*" headers="*"/> </cross-domain-policy>
Скрин запущенного приложения

Исходники проекта
В следующей статье усложним задачу и будем передавать JSON данные из Silverlight в PHP.

#1 by Денис on 2010.03.22 - 10:09
Достать нынче дешевый Windows хостинг легко и дорого…
Да здравствует великий и могучий русский речь
Ну это я так, придираюсь, статья интересная, мало ли, пригодится.
PS. Вопрос возник – а нельзя для этого всего веб-сервисы заюзать. На PHP же можно сервис реализовать, а из Silverlight’а его дернуть?
#2 by AlexandrYZ on 2010.03.22 - 10:26
Это игра слов
До веб-сервисов на PHP я еще не дошел, но про это я тоже напишу.
#3 by Матвей on 2010.04.13 - 16:26
Привет очень интересный пост, я скачаал исходники но незнаю как запустить это приложение чтоб посмотреть как оно в дейстивии работает)) почему то не могу я к этому файлику обратиться (index.php)…в двух словах мог бы рассказать как php и silverlight проекты)) с уважением, Матвей)