|
-
Sockets and policy-file-request [PHP-AS3]
I'm working on a multi-user app, and using sockets for communication. I can connect fine when using either localhost, 127.0.0.1, or my IP when running the swf from the harddrive. I need to be able to server a response to the <policy-file-request> to be able to connect across domains. I can't use the standard http method since the final socket server may be on a server with no http server (load balancing is still in the works).
How do you format the response to the <policy-file-request> when using a PHP socket server? Do I need to send XML headers first, or just the XML itself?
Here's the server code:
PHP Code:
#!/usr/bin/php -q
<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$address = '192.168.2.4';
$port = 9999;
//---- Function to Send out Messages to Everyone Connected ----------------------------------------
function send_Message($allclient, $buf) {
global $client_list;
foreach($allclient as $client) {
if($client_list[$client]['state'] && $client_list[$client]['nick'] != ""){
socket_write($client, trim($buf).chr(0));
}
}
}
//---- Function to Send List of Everyone Connected ----------------------------------------
function who($allclient, $socket) {
global $client_list;
$buf = "";
$counter = 0;
foreach($allclient as $client) {
$buf.=$client_list[$client]['nick'].", ";
$counter++;
}
socket_write($socket, "There are $counter people in this room: $buf".chr(0));
}
//---- Function to Send out Messages to Individuals ----------------------------------------
function send_Single($socket, $buf) {
socket_write($socket, $buf.chr(0));
}
//---- Start Socket creation for PHP 5 Socket Server -------------------------------------
if (($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() failed, reason: " . socket_strerror($master) . "\n";
}
socket_set_option($master, SOL_SOCKET,SO_REUSEADDR, 1);
if (($ret = socket_bind($master, $address, $port)) < 0) {
echo "socket_bind() failed, reason: " . socket_strerror($ret) . "\n";
}
if (($ret = socket_listen($master, 5)) < 0) {
echo "socket_listen() failed, reason: " . socket_strerror($ret) . "\n";
}
$read_sockets = array($master);
$client_list = array($master);
//---- Create Persistent Loop to continuously handle incoming socket messages ---------------------
while (true) {
$changed_sockets = $read_sockets;
$num_changed_sockets = socket_select($changed_sockets, $write = NULL, $except = NULL, NULL);
foreach($changed_sockets as $socket) {
if ($socket == $master) {
//---- Accept Incoming Connections and Request Nickname ----------------------------------------
if (($client = socket_accept($master)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
continue;
} else {
echo "[connection]:$client\n";
array_push($read_sockets, $client);
$client_list[$client]['state'] = false;
send_Single($client, "<b>Enter a nickname:<b>");
}
} else {
//---- Grab Incoming Messages From all Users ----------------------------------------
$bytes = socket_recv($socket, $buffer, 2048, 0);
//---- Handle User Disconnects ----------------------------------------
if ($bytes == 0) {
$nick = $client_list[$socket]['nick'];
$iindex = array_search($socket, $client_list);
unset($client_list[$iindex]);
$index = array_search($socket, $read_sockets);
unset($read_sockets[$index]);
socket_close($socket);
$allclients = $read_sockets;
array_shift($allclients);
if($client_list[$socket]['nick'] != "" && $client_list[$socket]['nick'] != "<policy-file-request/>"){
send_Message($allclients, "$nick has left the room");
}
}else{
if($bytes){
//---- Set Nickname ----------------------------------------
if($client_list[$socket]['state'] === false){
$client_list[$socket]['nick'] = $tempBuf = trim(trim($buffer));
echo $tempBuf." test";
send_Single($socket, "Hello $tempBuf! Welcome to the game!");
$allclients = $read_sockets;
array_shift($allclients);
who($allclients, $socket);
if($client_list[$socket]['nick'] != "" && $tempBuf != "<policy-file-request/>"){
send_Message($allclients, $client_list[$socket]['nick']." has entered the game.");
}
$client_list[$socket]['state'] = true;
}else{
//---- Check Message for Commands, and Respond or Broadcast Message ----------------------------------------
$allclients = $read_sockets;
array_shift($allclients);
if(trim($buffer) == "/who"){
who($allclients, $socket);
}else{
send_Message($allclients, $client_list[$socket]['nick']." wrote: ".$buffer);
}
}
}
}
}
}
}
?>
Here's the AS3 chat class (compiled with Flex/mxmlc):
PHP Code:
package{
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.net.*;
public class chat extends Sprite {
private var socket:XMLSocket;
private var msgArea:TextField = new TextField();
private var inputMsg:TextField = new TextField();
private var lastMessage:String = "";
private var connected:Boolean = false;
public function chat() {
msgArea.x=15;
msgArea.y=15;
msgArea.width=450;
msgArea.height=150;
msgArea.multiline=msgArea.border=msgArea.background=true;
addChild(msgArea);
inputMsg.x=15;
inputMsg.y=170;
inputMsg.width=415;
inputMsg.height=20;
inputMsg.type=TextFieldType.INPUT;
inputMsg.multiline=false;
inputMsg.selectable=inputMsg.border=inputMsg.background=true;
inputMsg.text="192.168.2.4";
addChild(inputMsg);
var pushMsg:Sprite = new Sprite();
var pushText:TextField = new TextField();
pushText.x=400;
pushText.y=170;
pushText.selectable=false;
pushText.autoSize='center';
pushText.text='Send';
pushText.border=pushText.background=true;
pushMsg.useHandCursor=true;
pushMsg.addChild(pushText);
pushMsg.addEventListener(MouseEvent.MOUSE_DOWN, msgGo);
addChild(pushMsg);
socket = new XMLSocket();
configureListeners(socket);
msgArea.htmlText = lastMessage = "<b>Enter IP address of the server, then click the \"Send\" button</b>";
}
private function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.CLOSE, closeHandler);
dispatcher.addEventListener(Event.CONNECT, connectHandler);
dispatcher.addEventListener(DataEvent.DATA, dataHandler);
dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
}
private function securityErrorHandler(event:SecurityErrorEvent):void {
msgArea.htmlText += "<br>securityErrorHandler: " + event;
}
private function connectHandler(success:Boolean):void {
if (success) {
msgArea.htmlText = lastMessage + '<br>' + '<b>Server connection established!</b>';
lastMessage = '<b>Server connection established!</b>';
connected = true;
} else {
msgArea.htmlText = lastMessage + '<br>' + '<b>Server connection failed!</b>';
lastMessage = '<b>Server connection failed!</b>';
}
}
private function closeHandler(event:Event):void {
msgArea.htmlText = lastMessage + '<br>' + '<b>Server connection lost</b>';
lastMessage = '<b>Server connection lost</b>';
}
private function dataHandler(event:DataEvent):void {
msgArea.htmlText = lastMessage + '<br>' + event.data;
lastMessage = event.data;
}
private function msgGo(event:MouseEvent):void{
if(!connected){
msgArea.htmlText = lastMessage = "<b>Contacting Server...</b>";
socket.connect(inputMsg.text,9999);
}else{
if (inputMsg.text != '') {
socket.send(inputMsg.text);
}
}
inputMsg.text = '';
}
}
}
And here's the AS2 version (compiled with Ming/PHP):
PHP Code:
<?
ming_useswfversion(7);
$movie=new SWFMovie(7);
$movie->setDimension(550,200);
$movie->setBackground(255,255,255);
$movie->setRate(30);
$actions="
createTextField('msgArea', getNextHighestDepth(), 15, 17, 450, 150);
with(msgArea){
border=background=html=wordWrap=mulitline=selectable=multiline=wordWrap=true;
}
createTextField('inputMsg', getNextHighestDepth(), 15, 170, 415, 20);
with(inputMsg){
border=background=true;
multiline=false;
type='input';
text='192.168.2.4';
}
inputMsg.onKeyPress=function(){
if(Key.isDown(Key.ENTER)){
pushMsg.onRelease();
}
};
createEmptyMovieClip('pushMsg',getNextHighestDepth());
pushMsg.createTextField('buttonText', pushMsg.getNextHighestDepth(), 455, 170, 0, 0);
with(pushMsg.buttonText){
border=background=true;
selectable=false;
autoSize='center';
text='Send';
}
mySocket = new XMLSocket();
connected = false;
mySocket.onConnect = function(success) {
if (success) {
msgArea.htmlText = lastMessage + '\n' + '<b>Server connection established!</b>';
lastMessage = '<b>Server connection established!</b>';
connected = true;
} else {
msgArea.htmlText = lastMessage + '\n' + '<b>Server connection failed!</b>';
lastMessage = '<b>Server connection failed!</b>';
}
};
mySocket.onClose = function() {
msgArea.htmlText = lastMessage + '\n' + '<b>Server connection lost</b>';
lastMessage = '<b>Server connection lost</b>';
};
var lastMessage = '';
XMLSocket.prototype.onData = function(msg) {
msgArea.htmlText = lastMessage + '\n' + msg;
lastMessage = msg;
};
msgArea.text = lastMessage = 'Enter IP address of the server, then click the \"Send\" button';
//--- Handle button click --------------------------------------
function msgGO() {
if(!connected){
msgArea.htmlText = lastMessage = '<b>Contacting Server...</b>';
mySocket.connect(inputMsg.text, 9999);
}else{
if (inputMsg.text != '') {
mySocket.send(inputMsg.text);
}
}
inputMsg.text = '';
}
pushMsg.onRelease = function() {
msgGO();
Selection.setFocus(inputMsg);
};
_keyListener = new Object();
Key.addListener(_keyListener);
_keyListener.onKeyDown=function(){
if(Key.getCode()==Key.ENTER){
pushMsg.onRelease();
}
};
";
$movie->add(new SWFAction($actions));
// save swf with same name as filename
$swfname = basename(__FILE__,".php");
$movie->save($outswf="$swfname.swf",9);
// open movie and set version to 8
// (hack until it can be set in ming)
$ftmp=fopen($outswf,"r");
$stmp=fread($ftmp,filesize($outswf));
$ftmp=fopen($outswf,"w");
fwrite($ftmp,substr_replace($stmp,chr(8),3,1));
$revitalizer=rand();
print "<html><body bgColor=\"#c6c6c6\"><center>
<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=8,0,0,0\" ID=objects WIDTH=\"550\" HEIGHT=\"200\">
<PARAM NAME=movie VALUE=\"$outswf?r=$revitalizer\">
<EMBED src=\"$outswf?r=$revitalizer\" WIDTH=\"550\" HEIGHT=\"200\" TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\">
</OBJECT>
<br><br>
<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=9,0,0,0\" ID=objects WIDTH=\"550\" HEIGHT=\"200\">
<PARAM NAME=movie VALUE=\"../flex/bin/chat.swf?r=$revitalizer\">
<EMBED src=\"../flex/bin/chat.swf?r=$revitalizer\" WIDTH=\"550\" HEIGHT=\"200\" TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\">
</OBJECT>
</center></body></html>
";
?>
Note- the above code outputs HTML to display both AS2 & AS3 versions on the same page, but only compiles the AS2 version via Ming.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|