1.FLASH 通过URL地址获得服务器数据。
这种方式最为简单,就像在浏览器的地址栏里面敲一样。
先建立一个URLRequest,然后用URLLoader载入就行了。
下面这个是载入一个图片,html页面也用同样方法载入。
//worldterminator原创,转载请注明此处
public function Net() { var loader:URLLoader; var request:URLRequest = new URLRequest("http://www.adobe.com/devnet/images/248x148/fldc_samples_3.jpg"); loader = new URLLoader(request); loader.addEventListener(Event.COMPLETE,completeListener); } function completeListener(event:Event):void { trace( "load completed "+loader.data+" are the data "); }
?
这种方法的缺点显而易见,大量的参数必须写到地址里,数据被暴露而且格式转换麻烦。
//worldterminator原创,转载请注明此处
2.通过AMF协议来通讯。
AMF协议是ADOBE自己开发的一种建立在HTTP基础上的协议。可以装一个flash mx remoting来实现或者装openAMF来实现,这里只讨论openAMF。先下载一个openAMF,最好带example版本的。然后把openamf.ear放到tomcat的webapps下,启动tomcat,输入
http://localhost:8080/openamf/gateway
假如看到空白页,说明openAMF好用了。如何用呢?
amf的通信方式是在服务器端把java的class放到web-inf的class中,然后在flash端直接调用这个class的方法就行了。
比如helloworld这个例子。
?
package abc; public class HelloServlet { public String hello() { return "this is java server!"; } }
?
用javac编译,把生成的class放到openAMF/classes/abc/
FLASH端这样写:
?
用javac编译,把生成的class放到openAMF/classes/abc/ FLASH端这样写:
?
建立一个netconnection,然后连接那个gateway,用call的方法调用java类的方法,格式是 包名.类名.方法名。至于返回值,用responder来接收,responder在接收到数据时会调用fun函数,把返回值写到fun函数的参数里。
?
3.socket方式通信
这种方法应该可以和任何语言通信,使用TCP/IP协议。但是,对于FLASH PLAYER 9及其以后的版本,比较麻烦的一点就是安全设置,
包括AMF方式在内,假如不设置会出现“安全沙箱”的错误。
FLASH 在连接服务器之前会发一个验证信息:内容如下:
<policy-file-request/>
对应的,你也应该发回一个验证信息,XML格式,一般可以这样写:
<cross-domain-policy><allow-access-from domain=/"*/" to-ports=/"*/" /></cross-domain-policy>/0
注重!假如把这个串存到字符串里发回去,不要忘记那个/0,XML都是以/0结尾的。
然后FLASH会主动断开,再执行连接,然后才算连上。
//worldterminator原创,转载请注明此处
先看FLASH端代码如何写:
?
socket = new Socket(); socket.addEventListener(ProgressEvent.SOCKET_DATA,receiveData); socket.addEventListener(Event.CONNECT,begin); socket.connect("127.0.0.1",843); function begin(event:Event):void { var s:String = "a/n"; socket.writeByte(s.charCodeAt(0)); socket.writeByte(s.charCodeAt(1)); socket.flush(); }
?
FLASH端比较简单,先connect,添加CONNECT事件,假如连上了,执行begin函数,会向服务器写两个byte。
接收的时候用 receivedData函数,函数里面可以这么写:
??? ??? socket.readBytes(received);
readBytes是把发过来的字符数组存到received里,当然还可以用socket别的方法读取数据。
相对于FLASH端,JAVA服务器端就比较麻烦了。
JAVA服务器这里我们用了多线程,因为可能有很多人访问服务器。先说一下代码思路,main函数里建立一个serversocket,然后不断的接收请求,每收到一个请求,就建立一个进程,把对应的socket放到线程中。另外有一个sender取得所有线程socket的outputstream,实现广播功能。
?
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(843);
File x;
Thread receiver;
System.out.println("server start");
Sender sender = new Sender();
while (true)
{
Socket socket=null;
System.out.println("waiting...");
socket = ss.accept();
receiver = new Receiver(socket,sender);
System.out.println("connect from address: "+socket.getInetAddress());
receiver.start();
}
//System.out.println("server over");
}
}
?
//worldterminator原创,转载请注明此处
这个是非主线程运行的代码:
?
package for_flash_socket;
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Receiver extends Thread {
Socket socket;
final int BYTE_ARRAY_MAX_LEN = 1000;
final String FLASH_SAFE = "<policy-file-request/>";
static String safe = "<cross-domain-policy><allow-access-from domain=/"*/" to-ports=/"*/" /></cross-domain-
policy>/0";
Sender sender;
public Receiver(Socket socket,Sender sender )
{
this.socket = socket;
this.sender = sender;
}
@Override
public void run()
{
try
{
InputStream is = socket.getInputStream();
byte [] reader = new byte [BYTE_ARRAY_MAX_LEN];
BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(socket.getOutputStream()));
OutputStream out = socket.getOutputStream();
sender.addOutput(out);
int ch=0;
String s;
while ( is.read(reader) != -1 )
{
//System.out.println("ch - "+ch);
s = new String(reader);
System.out.println("reader len:"+reader.length);
System.out.println(s);
if ( s!=null && s.indexOf("<policy-file-request/>")>=0 )//安全策略
{
for ( int i=0;i<s.length();i++ )
{
System.out.println(i+" "+(int)s.charAt(i));
}
bw.write(safe,0,safe.length());
bw.flush();
//bw.close();
System.out.println(safe);
}
else
{
synchronized(sender)
{
sender.send(s);
}
}
reader = new byte [BYTE_ARRAY_MAX_LEN];
}
bw.close();
synchronized (sender)
{
sender.removeOutput(out);
}
}
catch (Exception ex)
{
System.out.println("error in receiver");
ex.printStackTrace();
}
try
{
socket.close();
System.out.println(socket.getInetAddress()+" disconnected");
} catch (IOException ex1) {
System.out.println("socket close error");
Logger.getLogger(Receiver.class.getName()).log(Level.SEVERE, null, ex1);
}
}
}
?//worldterminator原创,转载请注明此处
sender:
?
package for_flash_socket;
import java.util.*;
import java.io.*;
public class Sender {
ArrayList outputArrayList;
public Sender()
{
outputArrayList = new ArrayList();
}
public void addOutput(OutputStream out)
{
outputArrayList.add(out);
}
public void removeOutput(OutputStream out)
{
outputArrayList.remove(out);
}
public void send(String s)
{
for (int i=0;i<outputArrayList.size();i++)
{
PrintWriter pw = new PrintWriter((OutputStream)outputArrayList.get(i));
pw.write(s);
pw.flush();
}
}
}
?
线程那个部分代码写得比较搓,明白原理就行了……
//worldterminator原创,转载请注明此处
这样基本的通信功能就实现了,在接收的时候先判定一下发过来的是不是安全认证s.indexOf("<policy-file-request/>")>=0
假如是返回安全认证,就是那个safe字符串。
否则把发过来的信息广播出去。sender.send方法。
//worldterminator原创,转载请注明此处
要注重的是:
?while ( is.read(reader) != -1 )这一行
我一开始用的是BufferedReader readLine()方法读取的。总是莫名奇妙的出错,所以建议不要用BufferedReader,直接读取byte或者byte数组的方式比较好。再把byte[]转成string判定是否是FLASH发过来的安全认证。
假如出现安全沙箱错误,一般是安全认证没有返回,但是别的情况也有可能出现这个错误,比如服务器的socket关闭早了,或者服务器没有把socket流内的内容读取完毕就关闭了,都会导致这个错误。
所以socket读到不能再读,然后再关闭,这个地方需要注重。
还有一个用XMLSocket的方式通信的,和socket差不多,这里不多说了,安全认证也是一样的,比socket简单一些。
这样,就完成了基本的 FLASH与JAVA 通信。