- TAG ET KIG I BUNDEN - FIK LØST PROBLEMET -
Jamen her er så mit lille delikate problem. Meget mystisk problem hvis i spørger mig.
Jeg har en .NET server som kan modtage TCP Forbindelser på port 4900 (asynkron og high performance og det hele, har selv skrevet den og tør godt sige at mit problem ikke ligger deri da jeg har brugt den til meget andet).
Så har jeg en Flash client som kan forbinde til port 4900 på min server via en socket. Jeg er nok lidt af en tumpe i ActionScript 3, så det går vidst ikke helt godt.
Jeg har en Policy server (som virker) kørende på serveren.
Jeg kan sagtens få forbindelse fra Flash til serveren, og jeg (se koden nedeunder) sender successfuldt en "welcome besked" til serveren og serveren svarer også igen.
Hvis jeg trykker på en knap på serveren, så pusher den en besked til Flash som flash så viser.
Mit problem er at jeg laver en socket "proxy" for Javascript. Når Flash modtager en besked kalder det javascript via ExternalInterface (virker!) og Javascript kan ligeledes kalde Flash via et ExternalInterface callback. Det sidste her virker ikke. Javascript -> Flash delen virker, da jeg i min eksempelkode får besked fra både javascript funktionen og respons fra Flash om at funktionen er aktiveret.
Men den sender aldrig noget data af sted via den socket, selvom nøjagtig samme kode der bare bliver kaldt ved forbindelse virker perfekt?
Er der nogle der kan regne det her ud?
import flash.net.Socket;
import flash.events.*;
import flash.external.ExternalInterface;
var socket:Socket = new Socket();
Security.allowDomain("*");
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);
socket.connect("privatserverher", 4900);
ExternalInterface.addCallback("sendToActionscript", callFromJavaScript);
function callFromJavaScript(dir):void
{
ExternalInterface.call("mesaway", "PRE FLASH");
socket.writeUTFBytes("UBER CHAT FTW!\n");
socket.writeUTFBytes("\n");
ExternalInterface.call("mesaway", "POST FLASH");
}
function onConnect(e:Event):void {
//Det er copy pasted så bruger bare det her som test.
//Det er HTTP headers men det er min server ligeglad med.
//Den kører bare rå UTF-8 uden nogen logik i lige nu
//Hvor den kun viser beskeder der kommer ind på skærmen
//Og kan sende simple svar. Alle sammen med en NULL byte efter
//Så flash kan forstå dem (virker fra server til client).
socket.writeUTFBytes("GET / HTTP/1.1\n");
socket.writeUTFBytes("Host: hejp.co.uk\n");
socket.writeUTFBytes("\n");
}
function onClose(e:Event):void {
// Security error is thrown if this line is excluded
ExternalInterface.call("mesaway", "SOCK CLOSE");
socket.close();
}
function onError(e:IOErrorEvent):void {
ExternalInterface.call("mesaway", "IO ERROR");
}
function onSecError(e:SecurityErrorEvent):void {
ExternalInterface.call("mesaway", "SEC ERROR");
}
function onResponse(e:ProgressEvent):void {
if (socket.bytesAvailable>0) {
ExternalInterface.call("test", socket.readUTFBytes(socket.bytesAvailable));
}
}
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
- <title>SurikatChat</title>
- <script type="text/javascript">
- function getFlashMovie(movieName) {
- var isIE = navigator.appName.indexOf("Microsoft") != -1;
- return (isIE) ? window[movieName] : document[movieName];
- }
- function callToActionscript(str)
- {
- alert("PRE");
- getFlashMovie("SurikatChat").sendToActionscript(str);
- alert("POST");
- }
- function test(val)
- {
- alert(val);
- }
-
- function mesaway(val)
- {
- alert(val);
- }
- </script>
- <script language="JavaScript" type="text/javascript">
- <!--
- //v1.7
- // Flash Player Version Detection
- // Detect Client Browser type
- // Copyright 2005-2008 Adobe Systems Incorporated. All rights reserved.
- var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
- var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
- var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
- function ControlVersion()
- {
- var version;
- var axo;
- var e;
- // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
- try {
- // version will be set for 7.X or greater players
- axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
- version = axo.GetVariable("$version");
- } catch (e) {
- }
- if (!version)
- {
- try {
- // version will be set for 6.X players only
- axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
-
- // installed player is some revision of 6.0
- // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
- // so we have to be careful.
-
- // default to the first public version
- version = "WIN 6,0,21,0";
- // throws if AllowScripAccess does not exist (introduced in 6.0r47)
- axo.AllowScriptAccess = "always";
- // safe to call for 6.0r47 or greater
- version = axo.GetVariable("$version");
- } catch (e) {
- }
- }
- if (!version)
- {
- try {
- // version will be set for 4.X or 5.X player
- axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
- version = axo.GetVariable("$version");
- } catch (e) {
- }
- }
- if (!version)
- {
- try {
- // version will be set for 3.X player
- axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
- version = "WIN 3,0,18,0";
- } catch (e) {
- }
- }
- if (!version)
- {
- try {
- // version will be set for 2.X player
- axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
- version = "WIN 2,0,0,11";
- } catch (e) {
- version = -1;
- }
- }
-
- return version;
- }
- // JavaScript helper required to detect Flash Player PlugIn version information
- function GetSwfVer(){
- // NS/Opera version >= 3 check for Flash plugin in plugin array
- var flashVer = -1;
-
- if (navigator.plugins != null && navigator.plugins.length > 0) {
- if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
- var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
- var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
- var descArray = flashDescription.split(" ");
- var tempArrayMajor = descArray[2].split(".");
- var versionMajor = tempArrayMajor[0];
- var versionMinor = tempArrayMajor[1];
- var versionRevision = descArray[3];
- if (versionRevision == "") {
- versionRevision = descArray[4];
- }
- if (versionRevision[0] == "d") {
- versionRevision = versionRevision.substring(1);
- } else if (versionRevision[0] == "r") {
- versionRevision = versionRevision.substring(1);
- if (versionRevision.indexOf("d") > 0) {
- versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
- }
- }
- var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
- }
- }
- // MSN/WebTV 2.6 supports Flash 4
- else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
- // WebTV 2.5 supports Flash 3
- else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
- // older WebTV supports Flash 2
- else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
- else if ( isIE && isWin && !isOpera ) {
- flashVer = ControlVersion();
- }
- return flashVer;
- }
- // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
- function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
- {
- versionStr = GetSwfVer();
- if (versionStr == -1 ) {
- return false;
- } else if (versionStr != 0) {
- if(isIE && isWin && !isOpera) {
- // Given "WIN 2,0,0,11"
- tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"]
- tempString = tempArray[1]; // "2,0,0,11"
- versionArray = tempString.split(","); // ['2', '0', '0', '11']
- } else {
- versionArray = versionStr.split(".");
- }
- var versionMajor = versionArray[0];
- var versionMinor = versionArray[1];
- var versionRevision = versionArray[2];
- // is the major.revision >= requested major.revision AND the minor version >= requested minor
- if (versionMajor > parseFloat(reqMajorVer)) {
- return true;
- } else if (versionMajor == parseFloat(reqMajorVer)) {
- if (versionMinor > parseFloat(reqMinorVer))
- return true;
- else if (versionMinor == parseFloat(reqMinorVer)) {
- if (versionRevision >= parseFloat(reqRevision))
- return true;
- }
- }
- return false;
- }
- }
- function AC_AddExtension(src, ext)
- {
- if (src.indexOf('?') != -1)
- return src.replace(/\?/, ext+'?');
- else
- return src + ext;
- }
- function AC_Generateobj(objAttrs, params, embedAttrs)
- {
- var str = '';
- if (isIE && isWin && !isOpera)
- {
- str += '<object ';
- for (var i in objAttrs)
- {
- str += i + '="' + objAttrs[i] + '" ';
- }
- str += '>';
- for (var i in params)
- {
- str += '<param name="' + i + '" value="' + params[i] + '" /> ';
- }
- str += '</object>';
- }
- else
- {
- str += '<embed ';
- for (var i in embedAttrs)
- {
- str += i + '="' + embedAttrs[i] + '" ';
- }
- str += '> </embed>';
- }
- document.write(str);
- }
- function AC_FL_RunContent(){
- var ret =
- AC_GetArgs
- ( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
- , "application/x-shockwave-flash"
- );
- AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
- }
- function AC_SW_RunContent(){
- var ret =
- AC_GetArgs
- ( arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
- , null
- );
- AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
- }
- function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
- var ret = new Object();
- ret.embedAttrs = new Object();
- ret.params = new Object();
- ret.objAttrs = new Object();
- for (var i=0; i < args.length; i=i+2){
- var currArg = args[i].toLowerCase();
- switch (currArg){
- case "classid":
- break;
- case "pluginspage":
- ret.embedAttrs[args[i]] = args[i+1];
- break;
- case "src":
- case "movie":
- args[i+1] = AC_AddExtension(args[i+1], ext);
- ret.embedAttrs["src"] = args[i+1];
- ret.params[srcParamName] = args[i+1];
- break;
- case "onafterupdate":
- case "onbeforeupdate":
- case "onblur":
- case "oncellchange":
- case "onclick":
- case "ondblclick":
- case "ondrag":
- case "ondragend":
- case "ondragenter":
- case "ondragleave":
- case "ondragover":
- case "ondrop":
- case "onfinish":
- case "onfocus":
- case "onhelp":
- case "onmousedown":
- case "onmouseup":
- case "onmouseover":
- case "onmousemove":
- case "onmouseout":
- case "onkeypress":
- case "onkeydown":
- case "onkeyup":
- case "onload":
- case "onlosecapture":
- case "onpropertychange":
- case "onreadystatechange":
- case "onrowsdelete":
- case "onrowenter":
- case "onrowexit":
- case "onrowsinserted":
- case "onstart":
- case "onscroll":
- case "onbeforeeditfocus":
- case "onactivate":
- case "onbeforedeactivate":
- case "ondeactivate":
- case "type":
- case "codebase":
- case "id":
- ret.objAttrs[args[i]] = args[i+1];
- break;
- case "width":
- case "height":
- case "align":
- case "vspace":
- case "hspace":
- case "class":
- case "title":
- case "accesskey":
- case "name":
- case "tabindex":
- ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
- break;
- default:
- ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
- }
- }
- ret.objAttrs["classid"] = classid;
- if (mimeType) ret.embedAttrs["type"] = mimeType;
- return ret;
- }
- // -->
- </script>
- </head>
- <body bgcolor="#ffffff">
- <!--url's used in the movie-->
- <!--text used in the movie-->
- <!-- saved from url=(0013)about:internet -->
- <script language="JavaScript" type="text/javascript">
- AC_FL_RunContent(
- 'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0',
- 'width', '550',
- 'height', '400',
- 'src', 'SurikatChat',
- 'quality', 'high',
- 'pluginspage', 'http://www.adobe.com/go/getflashplayer',
- 'align', 'middle',
- 'play', 'true',
- 'loop', 'true',
- 'scale', 'showall',
- 'wmode', 'window',
- 'devicefont', 'false',
- 'id', 'SurikatChat',
- 'bgcolor', '#ffffff',
- 'name', 'SurikatChat',
- 'menu', 'true',
- 'allowFullScreen', 'false',
- 'allowScriptAccess','sameDomain',
- 'movie', 'SurikatChat',
- 'salign', ''
- ); //end AC code
- </script>
- <noscript>
- <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="550" height="400" id="SurikatChat" align="middle">
- <param name="allowScriptAccess" value="sameDomain" />
- <param name="allowFullScreen" value="false" />
- <param name="movie" value="SurikatChat.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /> <embed src="SurikatChat.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="SurikatChat" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" />
- </object>
- </noscript>
- <a href="#" onClick="javascript:callToActionscript('FTW');">TEST!</a>
- </body>
- </html>
Det er med 100% sikkerhed kodet grimt og lidt "sloppy" men det er bare en proof of concept prototype til et privat projekt så bær over med mig!
EDIT:
I må sgu undskylde at jeg er en klapthat klokken halv 3 om natten. Jeg tænkte "gad vide om nogle opensource projekter" gør det her. Så kiggede jeg lidt rundt og så et bibliotek der gør det samme som det her (men det er ikke det værd at bruge et helt bibliotek efter min mening, og man lærer mere af at skrive det selv)... Man skal åbenbart kalde socket.flush() efter man har skrevet til en socket i ActionScript. Det undrer mig lidt at den første kode virkede uden flush, men det er åbenbart nødvendigt for de bedste resultater.
Jeg ved i øvrigt godt at flush "skyller" databufferen ned i den underliggende stream så det kan blive sendt af sted, da tilsvarende funktion eksisterer i .NET. Plejer selv at kalde den der, men så vidt jeg har oplevet har det aldrig givet problemer hvis jeg udelod? (endnu i hvert fald).
Hvis et klogt hovede kan bringe noget lys på sagen ville det da være dejligt.
Indlæg senest redigeret d. 05.08.2011 06:19 af Bruger #14381