А теперь самое интересное - делаем простой сервер на Ruby и флэш-клиент, который будет обмениваться данными с этим сервером с помощью XMLSocket.
Сервера на Ruby нам не нужно бояться. Он очень простой, укладывается в 18 строк кода. Сам я весьма поверхносно знаю Ruby, а это сделано на основе готового решения, нарытого в инете:
#!/usr/bin/ruby -w
puts 'Debug Server v 0.01'
policyInfo = '<?xml version="1.0"?>'
policyInfo += '<cross-domain-policy>'
policyInfo += '<allow-access-from domain="*" to-ports="4444,80" />'
policyInfo += "</cross-domain-policy>\0"
require 'socket'
server = TCPServer.new('localhost', 4444);
while(session = server.accept)
Thread.new(session) do |s|
s.print policyInfo
while(msg = s.gets)
msg.strip!
puts msg
s.print msg
end
end
end
Сервер в бесконечном цикле ждет соединений от клиента. Для каждого соединения создает отдельный поток и сразу посылает клиенту policy-инфу, без которой флэш-плеер откажется работать с этим сокетом (подробности тут). Далее в следующем бесконечном цикле принимаются сообщения от клиента. Они выводятся в консоль и отправляются обратно клиенту. Вот и все.
Теперь клиентская часть:
/**
* @author Yzh
*/
package;
import flash.system.Security;
import flash.net.XMLSocket;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.DataEvent;
class TrySocket
{
// properties
private var socket: XMLSocket;
// constructor
public function new()
{
try
{
Security.loadPolicyFile('xmlsocket://localhost:4444');
trace('create socket');
this.socket = new XMLSocket('localhost', 4444);
this.socket.addEventListener(Event.CONNECT, OnConnect);
this.socket.addEventListener(DataEvent.DATA, OnData);
this.socket.addEventListener(Event.CLOSE, OnClose);
this.socket.addEventListener(IOErrorEvent.IO_ERROR, OnIOError);
this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, OnSecurityError);
}
catch(e:Dynamic)
{
trace('sluchilos strashnoe!');
trace(e.toString());
}
}
static public function main():Void
{
new TrySocket();
}
private function OnConnect(event:Event):Void
{
trace('Connected!');
trace('send some data');
this.socket.send('Hello\n');
this.socket.send('How do you do?\n');
this.socket.send('It`s work!!!\n');
}
private function OnData(event:DataEvent):Void
{
trace('OnData: ' + event.data);
}
private function OnClose(event:Event):Void
{
trace('connection closed');
}
private function OnIOError(event:IOErrorEvent):Void
{
trace('OnIOError');
trace(event.toString());
}
private function OnSecurityError(event:SecurityErrorEvent):Void
{
trace('OnSecurityError');
trace(event.toString());
}
public function toString():String { return 'TrySocket'; }
}
Первым делом мы загружаем policy-данные
Security.loadPolicyFile('xmlsocket://localhost:4444');
Ruby-сервер сообщает флэш-клиенту, что он разрешает соединения с любого домена на порты 4444 и 80. Если флэш-клиент не получит эти данные, возникнет событие
SecurityErrorEvent. Далее мы создаем
XMLSocket, ждем установления соединения (событие
Event.CONNECT), и пишем в сокет некоторые строки. Они отображаются в консоли сервера и возвращаются обратно клиенту, в метод
OnData. Если закрыть клиента, на сервере ничего особенного не произойдет -- он будет ждать других подключений. Если остановить сервер, в клиенте сработает событие
Event.CLOSE.
Хочу обратить внимание на один нюанс -- сервер должен заканчивать строку нулевым символом (zero byte), а клиент -- символом перевода строки.
В данном примере используется класс flash.net.XMLSocket, который работает со строковыми данными. Можно также использовать класс flash.net.Socket для работы с бинарными данными.
Дальше я собираюсь сделать дебаг-сервер на Ruby, который будет принимать отладочные сообщения от флэш-приложения и выводить их в консоль. А также, при необходимости, записывать их в лог-файл. Тогда отладка будет выглядеть следующим образом -- слева открыто окно с консолью дебаг-сервера, справа окно браузера и в нем флэш-приложение. Все, что во флэш-приложении передается функции trace, будет отображаться в консоли сервера.
Про отладку и возможности функции trace в haXe смотрите тут.