이 글은 tibyte.kr과 cafe.naver.com/sdbx에 게시됩니다.
(설명글은 http://cafe.naver.com/sdbx/737에 있습니다.)
플래시 클라이언트는 소켓서버에 연결할 때 정책파일(crossdomain.xml)을 달라는 요청을 보내는데 이 파일을 보내주지 않으면 통신을 시작할 수 없습니다.
클라이언트에서 Security.loadPolicyFile()메서드로 원격 서버와 같은 도메인에 연결하여 xml파일을 직접 받아올 수 있지만 그러지 못하는 상황에는 서버프로그램에서 이 정책파일을 직접 보내줄 수도 있습니다.
ActionScript 3.0으로 작성된 Adobe AIR 소켓서버 코드를 보겠습니다.
우선 ServerSocket객체를 만들고 bind()와 listen()을 수행하여 서버소켓을 가동시키는 함수입니다. (serverSocket은 이 클래스의 private멤버변수입니다.)
private function bind():void
{
//기존에 실행 중인 소켓서버가 있으면 닫고 새로 실행
if(serverSocket.bound)
{
serverSocket.close();
serverSocket = new ServerSocket();
}
serverSocket.bind(로컬포트, 로컬IP);
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnect);
serverSocket.listen();
//로그 코드 삽입
}
다음은 ServerSocketConnectEvent.CONNECT 이벤트가 발생했을 때 실행되는 onConnect함수입니다.
private function onConnect(event:ServerSocketConnectEvent):void
{
var socket:Socket = event.socket;
clientSockets[socket.remoteAddress] = 1;//연결된 클라이언트들을 배열로 관리
socket.addEventListener(Event.CLOSE, onClientDisconnect);//클라이언트가 접속을 끊었을 때
socket.addEventListener(ProgressEvent.SOCKET_DATA, onClientSocketCert);//클라이언트로부터 데이터가 들어올 때
//이 밖에도 다른 이벤트나 예외처리구문, 로그(기록) 남기는 구문들을 넣어줍니다.
}
연결이 되면 클라이언트는 서버로 메시지를 보내고 이에 따라 ProgressEvent.SOCKET_DATA 이벤트가 발생합니다.
클라이언트가 정책파일을 찾지 못했을 때는 843번 포트로 "<policy-file-request/>" 이라고 정책파일을 요청하는 메시지를 보냅니다. 따라서 서버에서는 저 메시지가 들어왔을 때 정책파일을 보내주어야 합니다.
private function onClientSocketCert(event:ProgressEvent):void
{
var socket:Socket = event.target as Socket;
var message:String = socket.readUTFBytes(socket.bytesAvailable);
if (message == "<policy-file-request/>") {
var policy:String = "<cross-domain-policy>" +
"<allow-access-from domain=\"*.example.com\" to-ports=\"8800\"/>" +
"</cross-domain-policy>\x00";
socket.writeUTFBytes(policy);
socket.flush();
socket.close();
} else if(message=="BEGIN") {
socket.removeEventListener(ProgressEvent.SOCKET_DATA, onClientSocketCert);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onClientSocketData);
socket.writeUTFBytes("READY");
socket.flush();
}
//이 밖에도 로그 남기는 코드를 삽입
}
위 함수에서 볼 수 있듯이 XML파일을 문자열형태로 직접 전송합니다.
"<cross-domain-policy>" +
"<allow-access-from domain=\"*.example.com\" to-ports=\"8800\"/>" +
"</cross-domain-policy>\x00"
(여기서 쓴 8800번 포트는 임의로 정한 포트번호입니다.)
크로스도메인(crossdomain.xml)파일에서 도메인과 포트를 지정해주는데요, 와일드카드 문자를 쓸 수 있습니다.