as3 Air ServerSocket支持websocket,实现服务端websocket
这几天在研究html5的东西,看到html5支持websocket,但是服务端怎么写呢?怎么实现呢?于是搜索了一下,网上Java,php实现的一大堆,用Air实现服务端就少了,找到一篇文章,实现了握手协议,发送消息怎么解决呢。去看了一下Wiki的解释,只要服务端跟客户端握手后,服务端跟客户就可以直接发信息了,他们是以\x00开始,\xFF结尾表示一条完整消息。所以我把完整的代码跑了一遍。
可以用下面的客户端进行测试:http://www.websocket.org/echo.html,用google chrome和safari浏览器
具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
private
var
socketServer:ServerSocket;
private
var
firstRequestProcessed:
Boolean
;
protected
function
windowedapplication1_creationCompleteHandler(event:FlexEvent):
void
{
// TODO Auto-generated method stub
socketServer =
new
ServerSocket();
socketServer.addEventListener(ServerSocketConnectEvent.CONNECT,clientHandler);
socketServer.bind(
1235
);
socketServer.listen();
trace
(
"test"
);
}
protected
function
clientHandler(event:ServerSocketConnectEvent):
void
{
// TODO Auto-generated method stub
var
socket:Socket = event.socket;
socket.addEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
}
protected
function
socketDataHandler(event:ProgressEvent):
void
{
// TODO Auto-generated method stub
var
socket:Socket = event.currentTarget
as
Socket;
var
socketBytes:ByteArray =
new
ByteArray();
if
(socket.bytesAvailable >
0
)
{
socket.readBytes(socketBytes);
if
(!firstRequestProcessed)
{
firstRequestProcessed =
true
;
var
message:
String
= socketBytes.readUTFBytes(socketBytes.bytesAvailable);
trace
(message);
if
(message.indexOf(
"GET "
) ==
0
)
{
var
messageLines:
Array
= message.split(
"\n"
);
var
fields:
Object
= {};
var
requestedURL:
String
=
""
;
for
(
var
i:
uint
=
0
; i < messageLines.length; i++)
{
var
line:
String
= messageLines[i];
if
(i ==
0
)
{
var
getSplit:
Array
= line.split(
" "
);
if
(getSplit.length >
1
)
{
requestedURL = getSplit[
1
];
}
}
else
{
var
index:
int
= line.indexOf(
":"
);
if
(index > -
1
)
{
var
key:
String
= line.substr(
0
, index);
fields[key] = line.substr(index +
1
).replace( /^([\s|\t|\n]+)?(.*)([\s|\t|\n]+)?$/gm,
"$2"
);
}
}
}
//check the websocket version
if
(fields[
"Sec-WebSocket-Version"
] !=
null
)
{
//NOT SUPPORTED YET
}
else
{
if
(fields[
"Sec-WebSocket-Key1"
] !=
null
&& fields[
"Sec-WebSocket-Key2"
] !=
null
)
{
//draft-ietf-hybi-thewebsocketprotocol-00
//send a response
var
result:* = fields[
"Sec-WebSocket-Key1"
].match(/[
0
-
9
]/gi);
var
key1Nr:
uint
= (result
is
Array
) ?
uint
(result.join(
""
)) :
1
;
result = fields[
"Sec-WebSocket-Key1"
].match(/ /gi);
var
key1SpaceCount:
uint
= (result
is
Array
) ? result.length :
1
;
var
key1Part:
Number
= key1Nr / key1SpaceCount;
result = fields[
"Sec-WebSocket-Key2"
].match(/[
0
-
9
]/gi);
var
key2Nr:
uint
= (result
is
Array
) ?
uint
(result.join(
""
)) :
1
;
result = fields[
"Sec-WebSocket-Key2"
].match(/ /gi);
var
key2SpaceCount:
uint
= (result
is
Array
) ? result.length :
1
;
var
key2Part:
Number
= key2Nr / key2SpaceCount;
//calculate binary md5 hash
var
bytesToHash:ByteArray =
new
ByteArray();
bytesToHash.writeUnsignedInt(key1Part);
bytesToHash.writeUnsignedInt(key2Part);
bytesToHash.writeBytes(socketBytes, socketBytes.length -
8
);
//hash it
var
hash:
String
= MD5.hashBytes(bytesToHash);
var
response:
String
=
"HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
+
"Upgrade: WebSocket\r\n"
+
"Connection: Upgrade\r\n"
+
"Sec-WebSocket-Origin: "
+ fields[
"Origin"
] +
"\r\n"
+
"\r\n"
;
var
responseBytes:ByteArray =
new
ByteArray();
responseBytes.writeUTFBytes(response);
for
(i =
0
; i < hash.length; i +=
2
)
{
responseBytes.writeByte(
parseInt
(hash.substr(i,
2
),
16
));
}
responseBytes.writeByte(
0
);
responseBytes.position =
0
;
socket.writeBytes(responseBytes);
socket.flush();
//stop right here
return
;
}
}
}
}
else
{
//do something else with the data
socketBytes.position =
1
;
trace
(
"FromClient:"
,socketBytes.readUTFBytes(socketBytes.bytesAvailable-
1
));
var
sendBytes:ByteArray =
new
ByteArray();
sendBytes.writeByte(
0
);
sendBytes.writeUTFBytes(
"Hello My Friends"
);
sendBytes.writeByte(
255
);
socket.writeBytes(sendBytes);
socket.flush();
}
}
}
|