本文主要是介绍用as3 serverSocket 做服务端,实现web客户端,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
听说,AIR2.0 有serverSocket可以做服务端,一时兴起,于是来试试,在官方看了一个示例,挺简单的(ps简单就意味着功能太少),就想来做一个聊天服务器(之前学完用FMS做聊天室,但毕竟是第三方服务器,受限制的,始终希望能自己做服务器,改天学C++);
最初都是用的air应用做的客户端连接不成问题。后来做web的客户端,连接不成功,服务端收到消息<policy-file-request/> 客户端提示安全性错误,Erorr:#2048 对于服务端的消息最初并不懂啥意思,于是摆渡。资料到是不少,意思是说,web客户端需要客户端提供安全策略文件,也就是crossdomain.xml,我检查http服务器根目录也有这个文件,并且内容如下:
<?xml version="1.0" ?>
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>
想想不对,这是客户端找服务端要文件,又以为是服务端应用程序的相同目录也要放一个,于是也放一个进去(是不是挺傻的);测试,还是不行;再摆渡,搜到了flashPlayer的socket读取安全策略的原理,原来flashPlayer 最初会去服务端的843端口找策略文件,找不到然后才去指定的端口找,如果都没有crossdomain,就会抛出安全错误。 在网上找资料,是说要单独建一个843端口服务端,专门侦听843端,都是用的java服务端(Java俺也不怎么懂); 不过我只看了一个关键性代码如下:
var xml:XML =<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain=\"*\" to-ports=\"*\"/>
</cross-domain-policy>
那些 \ 我不懂是干啥的,我放到FB 里不正常,要把四个 \ 都去掉,反正大致原理就是:843服务端收到客户端请求时,就把这个xml发送给客户端,然后再把socket关掉,由于843端口把客户端关了,客户端会重新连接,因为flashplayer之前收到了策略文件,可以访问服务端,所以就不会再去找843端口,直接连接到正常的服务端口去。
我不懂JAVA ,所以就用air单独又建一个服务端,端口为843;FB源代码如下:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="300" height="300" creationComplete="init()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import flash.events.ServerSocketConnectEvent;
import flash.net.ServerSocket;
import flash.net.Socket;
private var serverSocket:ServerSocket;
private var localIP:String="192.168.1.253";//我的电脑IP
private var localPort:int=843; //一定要是843端口
protected function init():void{
serverSocket = new ServerSocket();
serverSocket.bind(localPort,localIP );
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnect );
serverSocket.listen();
}
//客户端连接事件;
protected function onConnect(e:ServerSocketConnectEvent):void{
var tmpsocket:Socket=e.socket;
var xml:XML =<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*"/>
</cross-domain-policy>
tmpsocket.writeUTFBytes(xml.toString());
tmpsocket.flush();
log("发送策略文件到:"+xml.toString()+tmpsocket.remoteAddress+":"+tmpsocket.remotePort)
//关掉
tmpsocket.close();
}
//显示消息;
protected function log(str:String):void{
tmsg.appendText(str+"\n");
}
]]>
</fx:Script>
<s:TextArea id="tmsg" x="48" y="11" editable="false" enabled="true"/>
</s:WindowedApplication>
以下是web客户端源代码:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="500" height="400" minWidth="500" minHeight="500">
<fx:Script>
<![CDATA[
import flash.events.*;
import flash.net.Socket;
import flash.utils.ByteArray;
private var localIP:String="192.168.1.253";
private var localPort:int=8888;
private var socket:Socket;
protected function bt_conn_clickHandler(event:MouseEvent):void
{ socket=new Socket();
socket.connect(localIP,localPort);
socket.addEventListener(Event.CONNECT,onconnect);
socket.addEventListener(IOErrorEvent.IO_ERROR,onError);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onseError);
socket.addEventListener(ProgressEvent.SOCKET_DATA,onData);
}
private function onconnect(e:Event):void{
log("连接成功");
}
private function onError(e:IOErrorEvent):void{
log("连接失败,服务器没打开!")
}
private function onseError(e:SecurityErrorEvent):void{
log("连接失败,安全错误"+e.text)
}
//按钮发送
protected function bt_send_clickHandler(event:MouseEvent):void
{
sendmsg()
}
//接收到消息
protected function onData(e:ProgressEvent):void{
var ba:ByteArray=new ByteArray()
var tmpsocket:Socket=e.target as Socket;
tmpsocket.readBytes(ba,0,tmpsocket.bytesAvailable);
log(ba.toString());
}
//发送消息;
private function sendmsg():void{
if(text_input.text!=""){
socket.writeUTFBytes(text_input.text)
socket.flush();
text_input.text="";
}else{
log("不能发送空消息");
}
}
//显示消息
private function log(str:String):void{
text_msg.appendText(str+"\n")
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button id="bt_conn" x="10" y="348" label="连接" click="bt_conn_clickHandler(event)"/>
<s:Button id="bt_send" x="381" y="352" label="发送" click="bt_send_clickHandler(event)"/>
<s:TextInput id="text_input" x="122" y="319" width="251" height="54" enabled="true"
enter="sendmsg()" prompt="输入消息"/>
<s:TextArea id="text_msg" x="121" y="93" width="209" height="192" editable="false"
enabled="true"/>
</s:Application>
AIR serverSocket服务端源代码:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="500" height="500">
<fx:Script>
<![CDATA[
import flash.events.ServerSocketConnectEvent;
import flash.net.ServerSocket;
import flash.net.Socket;
import flash.utils.ByteArray;
private var serverSocket:ServerSocket;
private var localIP:String="192.168.1.253";
private var localPort:int=8888;
private var clientList:Array=[];
protected function bt_bind_clickHandler(event:MouseEvent):void
{
serverSocket = new ServerSocket();
serverSocket.bind(localPort,localIP);
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnect );
serverSocket.listen();
log("绑定到:"+serverSocket.localAddress+":"+serverSocket.localPort);
}
protected function onConnect(e:ServerSocketConnectEvent):void{
var tmpsocket:Socket=e.socket
clientList.push(tmpsocket);
tmpsocket.addEventListener(Event.CLOSE,onClose);
tmpsocket.addEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
tmpsocket.writeUTFBytes("服务器消息:你已连接到服务器")
tmpsocket.flush();
log("有新连接"+e.socket.remoteAddress+":"+e.socket.remotePort);
}
protected function onClose(e:Event):void{
for (var clt:int=0;clt<clientList.length;clt++){
if(clientList[clt].remoteAddress==e.target.remoteAddress){
clientList.splice(clt,1);
}
}
log(e.target.remoteAddress+"断开")
}
protected function onSocketData(e:ProgressEvent):void{
var tmpsocket:Socket=e.target as Socket;
var ba:ByteArray=new ByteArray()
tmpsocket.readBytes(ba,0,e.target.bytesAvailable)
var msg:String=ba.toString();
if(msg.indexOf("<policy-file-request/>")>-1){
log("不安全的客户端");
}else{
for each(var clt:Socket in clientList){
clt.writeUTFBytes(tmpsocket.remoteAddress+":"+tmpsocket.remotePort+"消息:"+msg);
clt.flush();
}
log("收到"+tmpsocket.remoteAddress+"消息:"+msg);
}
}
protected function bt_send_clickHandler(event:Event):void
{
sendmsg()
}
private function sendmsg():void{
if(clientList.length>0){
for each(var clt:Socket in clientList){
clt.writeUTFBytes("服务器消息:"+text_send.text);
clt.flush();
log("消息已发送:"+clt.remoteAddress+":"+text_send.text);
}
}else{
log("当前无连接!")
}
text_send.text="";
}
protected function log(str:String):void{
tr.appendText(str+"\n");
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button id="bt_bind" x="36" y="78" label="创建服务器" click="bt_bind_clickHandler(event)"/>
<s:TextArea id="tr" x="41" y="124" width="243" height="196" contentBackgroundAlpha="0.73"
editable="false" enabled="true"/>
<s:Button id="bt_send" x="319" y="385" width="52" label="发送" click="bt_send_clickHandler(event)"/>
<s:TextInput id="text_send" x="64" y="352" width="222" height="54" enabled="true" enter="sendmsg()"/>
</s:WindowedApplication>
这篇关于用as3 serverSocket 做服务端,实现web客户端的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!